millfork/src/main/scala/millfork/CompilationOptions.scala

655 lines
25 KiB
Scala

package millfork
import millfork.buildinfo.BuildInfo
import millfork.compiler.LabelGenerator
import millfork.error.{ConsoleLogger, Logger}
import millfork.parser.TextCodecRepository
/**
* @author Karol Stasiak
*/
case class CompilationOptions(platform: Platform,
commandLineFlags: Map[CompilationFlag.Value, Boolean],
outputFileName: Option[String],
zpRegisterSize: Int,
featureOverrides: Map[String, Long],
textCodecRepository: TextCodecRepository,
jobContext: JobContext) {
import CompilationFlag._
import Cpu._
@inline
def log: Logger = jobContext.log
@inline
def nextLabel: LabelGenerator = jobContext.nextLabel
@inline
def isBigEndian: Boolean = platform.isBigEndian
val flags: Map[CompilationFlag.Value, Boolean] = CompilationFlag.values.map { f =>
f -> commandLineFlags.getOrElse(f, platform.flagOverrides.getOrElse(f, Cpu.defaultFlags(platform.cpu)(f)))
}.toMap
def flag(f: CompilationFlag.Value): Boolean = flags(f)
{
log.setFatalWarnings(flags(CompilationFlag.FatalWarnings))
var invalids = Set[CompilationFlag.Value]()
if (CpuFamily.forType(platform.cpu) != CpuFamily.M6502) invalids ++= Set(
EmitCmosOpcodes, EmitCmosNopOpcodes, EmitHudsonOpcodes, EmitSC02Opcodes, EmitRockwellOpcodes, EmitWdcOpcodes, Emit65CE02Opcodes, EmitEmulation65816Opcodes, EmitNative65816Opcodes, LUnixRelocatableCode,
PreventJmpIndirectBug, LargeCode, ReturnWordsViaAccumulator, LUnixRelocatableCode, RorWarning, SoftwareStack)
if (CpuFamily.forType(platform.cpu) != CpuFamily.I80 && CpuFamily.forType(platform.cpu) != CpuFamily.I86) invalids ++= Set(
EmitIntel8085Opcodes, EmitIntel8080Opcodes, UseIxForStack, UseIntelSyntaxForInput, UseIntelSyntaxForOutput)
if (CpuFamily.forType(platform.cpu) != CpuFamily.I80) invalids ++= Set(
EmitExtended80Opcodes, EmitZ80Opcodes, EmitSharpOpcodes, EmitEZ80Opcodes, EmitZ80NextOpcodes,
UseIyForStack, UseIxForScratch, UseIyForScratch, UseShadowRegistersForInterrupts)
if (CpuFamily.forType(platform.cpu) != CpuFamily.M6809) invalids ++= Set(
UseUForStack, UseYForStack)
invalids = invalids.filter(flags)
if (invalids.nonEmpty) {
log.error("Invalid flags enabled for the current CPU family: " + invalids.mkString(", "))
}
if (CpuFamily.forType(platform.cpu) != CpuFamily.M6502 && zpRegisterSize > 0) {
log.error("Invalid flags enabled for the current CPU family: zp_register")
}
CpuFamily.forType(platform.cpu) match {
case CpuFamily.M6502 =>
if (flags(DecimalMode)) {
if (platform.cpu == Ricoh || platform.cpu == StrictRicoh) {
log.warn("Decimal mode enabled for Ricoh architecture")
}
}
if (platform.cpu == Sixteen) {
if (flags(LargeCode)) {
log.warn("Large code model doesn't work correctly yet")
}
}
if (platform.cpu != Sixteen) {
if (flags(LargeCode)) {
log.error("Cannot use large code model on architectures other than 65816")
}
if (flags(ReturnWordsViaAccumulator)) {
log.error("Cannot return words via accumulator on non-65816 architecture")
}
if (flags(EmitNative65816Opcodes) || flags(EmitEmulation65816Opcodes)) {
log.error("65816 opcodes enabled for non-65816 architecture")
}
}
if (platform.cpu != CE02) {
if (flags(Emit65CE02Opcodes)) {
log.error("65CE02 opcodes enabled for non-65CE02 architecture")
}
}
if (flags(Emit65CE02Opcodes)) {
log.warn("65CE02 opcodes are highly experimental")
}
if (platform.cpu != HuC6280) {
if (flags(EmitHudsonOpcodes)) {
log.error("HuC6280 opcodes enabled for non-HuC6280 architecture")
}
}
if (!CmosCompatible(platform.cpu)) {
if (!flags(PreventJmpIndirectBug)) {
log.warn("JMP bug prevention should be enabled for non-CMOS architecture")
}
if (flags(EmitCmosOpcodes)) {
log.error("CMOS opcodes enabled for non-CMOS architecture")
}
}
if (flags(EmitIllegals)) {
if (CmosCompatible(platform.cpu)) {
log.error("Illegal opcodes enabled for architecture that doesn't support them")
}
if (platform.cpu == StrictRicoh || platform.cpu == StrictMos) {
log.warn("Illegal opcodes enabled for strict architecture")
}
}
case CpuFamily.I80 =>
if (flags(EmitIllegals)) {
if (platform.cpu != Z80 && platform.cpu != Intel8085 && platform.cpu != Z80Next) {
log.error("Illegal opcodes enabled for architecture that doesn't support them")
}
}
if (flags(UseIxForStack) || flags(UseIxForScratch)) {
if (!Z80Compatible(platform.cpu)) {
log.error("IX register enabled for architecture that doesn't support it")
} else if (!flags(EmitZ80Opcodes)) {
log.error("IX register is enabled but instructions using it are disabled")
}
}
if (flags(UseIyForStack) || flags(UseIyForScratch)) {
if (!Z80Compatible(platform.cpu)) {
log.error("IY register enabled for architecture that doesn't support it")
} else if (!flags(EmitZ80Opcodes)) {
log.error("IY register is enabled but instructions using it are disabled")
}
}
if (flags(UseIxForScratch) && flags(UseIxForStack)) {
log.error("Cannot use the IX register for both stack variables and scratch simultaneously")
}
if (flags(UseIyForScratch) && flags(UseIyForStack)) {
log.error("Cannot use the IY register for both stack variables and scratch simultaneously")
}
if (flags(UseIxForStack) && flags(UseIyForStack)) {
log.error("Cannot use both IX and IY registers for stack variables simultaneously")
}
if (flags(UseShadowRegistersForInterrupts)) {
if (!Z80Compatible(platform.cpu)) {
log.error("Shadow registers enabled for architecture that doesn't support them")
} else if (!flags(EmitZ80Opcodes)) {
log.error("Shadow registers are enabled but instructions using them are disabled")
}
}
if (flags(EmitZ80Opcodes)) {
if (!Z80Compatible(platform.cpu)) {
log.error("Z80 opcodes enabled for architecture that doesn't support them")
}
}
if (flags(EmitEZ80Opcodes)) {
if (platform.cpu != EZ80) {
log.error("eZ80 opcodes enabled for architecture that doesn't support them")
}
}
if (flags(EmitSharpOpcodes)) {
if (platform.cpu != Sharp) {
log.error("Sharp LR35902 opcodes enabled for architecture that doesn't support them")
}
}
if (flags(EmitZ80NextOpcodes)) {
if (platform.cpu != Z80Next) {
log.error("ZX Spectrum Next opcodes enabled for architecture that doesn't support them")
}
}
if (flags(EmitExtended80Opcodes)) {
if (platform.cpu != Sharp && !Z80Compatible(platform.cpu)) {
log.error("Extended 8080-like opcodes enabled for architecture that doesn't support them")
}
}
if (flags(EmitIntel8080Opcodes)) {
if (!Intel8080Compatible(platform.cpu)) {
log.error("Intel 8080 opcodes enabled for architecture that doesn't support them")
}
}
if (flags(EmitIntel8085Opcodes)) {
if (!Intel8085Compatible(platform.cpu)) {
log.error("Intel 8085 opcodes enabled for architecture that doesn't support them")
}
}
if (!flags(CompilationFlag.EmitSharpOpcodes) && !flags(CompilationFlag.EmitIntel8080Opcodes)) {
log.error("Either Sharp LR35902 or Intel 8080 opcodes have to be enabled")
}
case CpuFamily.I86 =>
case CpuFamily.M6809 =>
if (flags(UseUForStack) && flags(UseYForStack)) {
log.error("Cannot use both U and Y registers for stack variables simultaneously")
}
if (!flags(UseUForStack) && !flags(UseYForStack)) {
log.error("You need to use either the U register or the Y register as the base pointer. This might be relaxed in the future.")
}
}
}
private def parseVersion(): Long = {
val tokens = BuildInfo.version.split("[.-]")
def extract(ix: Int):Int = {
tokens.lift(ix).filter(_ != "SNAPSHOT").getOrElse("0").toInt
}
val major = extract(0)
val minor = extract(1)
val patch = extract(2)
major * 10000 + minor * 100 + patch
}
def features: Map[String, Long] = {
@inline
def toLong(b: Boolean): Long = if (b) 1L else 0L
val featuresFromOptions = Map[String, Long](
"MILLFORK_VERSION" -> parseVersion(),
"OPTIMIZE_FOR_SIZE" -> toLong(flag(CompilationFlag.OptimizeForSize)),
"OPTIMIZE_FOR_SPEED" -> toLong(flag(CompilationFlag.OptimizeForSpeed)),
"OPTIMIZE_INLINE" -> toLong(flag(CompilationFlag.InlineFunctions)),
"OPTIMIZE_IPO" -> toLong(flag(CompilationFlag.InterproceduralOptimization)),
"CPUFEATURE_DECIMAL_MODE" -> toLong(flag(CompilationFlag.DecimalMode)),
"CPUFEATURE_Z80" -> toLong(flag(CompilationFlag.EmitZ80Opcodes)),
"CPUFEATURE_EZ80" -> toLong(flag(CompilationFlag.EmitEZ80Opcodes)),
"CPUFEATURE_8080" -> toLong(flag(CompilationFlag.EmitIntel8080Opcodes)),
"CPUFEATURE_8085" -> toLong(flag(CompilationFlag.EmitIntel8085Opcodes)),
"CPUFEATURE_GAMEBOY" -> toLong(flag(CompilationFlag.EmitSharpOpcodes)),
"CPUFEATURE_65C02" -> toLong(flag(CompilationFlag.EmitCmosOpcodes)),
"CPUFEATURE_65SC02" -> toLong(flag(CompilationFlag.EmitSC02Opcodes)),
"CPUFEATURE_ROCKWELL_65C02" -> toLong(flag(CompilationFlag.EmitRockwellOpcodes)),
"CPUFEATURE_WDC_65C02" -> toLong(flag(CompilationFlag.EmitWdcOpcodes)),
"CPUFEATURE_65CE02" -> toLong(flag(CompilationFlag.Emit65CE02Opcodes)),
"CPUFEATURE_HUC6280" -> toLong(flag(CompilationFlag.EmitHudsonOpcodes)),
"CPUFEATURE_65816_EMULATION" -> toLong(flag(CompilationFlag.EmitEmulation65816Opcodes)),
"CPUFEATURE_65816_NATIVE" -> toLong(flag(CompilationFlag.EmitNative65816Opcodes)),
"CPUFEATURE_6502_ILLEGALS" -> toLong(platform.cpuFamily == CpuFamily.M6502 && flag(CompilationFlag.EmitIllegals)),
"CPUFEATURE_Z80_ILLEGALS" -> toLong(flag(CompilationFlag.EmitZ80Opcodes) && flag(CompilationFlag.EmitIllegals)),
"CPUFEATURE_Z80_NEXT" -> toLong(flag(CompilationFlag.EmitZ80NextOpcodes)),
"CPUFEATURE_8085_ILLEGALS" -> toLong(flag(CompilationFlag.EmitIntel8080Opcodes) && flag(CompilationFlag.EmitIllegals)),
"BIG_ENDIAN" -> toLong(Cpu.isBigEndian(platform.cpu)),
"LITTLE_ENDIAN" -> toLong(!Cpu.isBigEndian(platform.cpu)),
"INIT_RW_MEMORY" -> toLong(platform.ramInitialValuesBank.isDefined),
"SYNTAX_INTEL" -> toLong(platform.cpuFamily == CpuFamily.I80 && flag(CompilationFlag.UseIntelSyntaxForInput)),
"SYNTAX_ZILOG" -> toLong(platform.cpuFamily == CpuFamily.I80 && !flag(CompilationFlag.UseIntelSyntaxForInput)),
"TINY_RW_MEMORY" -> toLong(platform.variableAllocators("default").totalHimemSize <= 256),
"USES_ZPREG" -> toLong(platform.cpuFamily == CpuFamily.M6502 && zpRegisterSize > 0),
"USES_IX_STACK" -> toLong(flag(CompilationFlag.UseIxForStack)),
"USES_IY_STACK" -> toLong(flag(CompilationFlag.UseIyForStack)),
"USES_U_STACK" -> toLong(flag(CompilationFlag.UseUForStack)),
"USES_Y_STACK" -> toLong(flag(CompilationFlag.UseYForStack)),
"USES_SOFTWARE_STACK" -> toLong(flag(CompilationFlag.SoftwareStack)),
"USES_SHADOW_REGISTERS" -> toLong(flag(CompilationFlag.UseShadowRegistersForInterrupts)),
"ZPREG_SIZE" -> (if (platform.cpuFamily == CpuFamily.M6502) zpRegisterSize.toLong else 0)
)
platform.features ++ featuresFromOptions ++ featureOverrides
}
}
object CpuFamily extends Enumeration {
/**
* Family based on the MOS 6502 processor and its descendants
*/
val M6502: CpuFamily.Value = Value
/**
* Family based on the Intel 8080 processor and similar architectures
*/
val I80: CpuFamily.Value = Value
/**
* Family based on the Motorola 6800 processor
*/
val M6800: CpuFamily.Value = Value
/**
* Family based on the Motorola 6809 processor
*/
val M6809: CpuFamily.Value = Value
/**
* Family based on the Intel 8086/8088 processor and its descendants
*/
val I86: CpuFamily.Value = Value
/**
* Family based on the Motorola 68000 processor and its descendants
*/
val M68K: CpuFamily.Value = Value
/**
* Family based on the ARM processors
*/
val ARM: CpuFamily.Value = Value
def forType(cpu: Cpu.Value): CpuFamily.Value = {
import Cpu._
cpu match {
case Mos | StrictMos | Ricoh | StrictRicoh | Cmos | SC02 | Rockwell | Wdc | HuC6280 | CE02 | Sixteen => M6502
case Intel8080 | Intel8085 | StrictIntel8085 | Sharp | Z80 | StrictZ80 | EZ80 | Z80Next => I80
case Intel8086 | Intel80186 => I86
case Cpu.Motorola6809 => M6809
}
}
def isBigEndian(family: CpuFamily.Value): Boolean = family match {
case M6502 | I80 | I86 | ARM => false
case M6800 | M6809 | M68K => true
}
}
object Cpu extends Enumeration {
/**
* The MOS 6502/6507/6510 processor
*/
val Mos: Cpu.Value = Value
/**
* The MOS 6502/6507/6510 processor, without illegal instructions
*/
val StrictMos: Cpu.Value = Value
/**
* The Ricoh 2A03/2A07 processor
*/
val Ricoh: Cpu.Value = Value
/**
* The Ricoh 2A03/2A07 processor, without illegal instructions
*/
val StrictRicoh: Cpu.Value = Value
/**
* The base 65C02 processor
*/
val Cmos: Cpu.Value = Value
/**
* The 65SC02 processor
*/
val SC02: Cpu.Value = Value
/**
* The Rockwell 65C02 processor
*/
val Rockwell: Cpu.Value = Value
/**
* The WDC 65C02 processor
*/
val Wdc: Cpu.Value = Value
/**
* The Hudson Soft HuC6280 processor
*/
val HuC6280: Cpu.Value = Value
/**
* The CSG 65CE02 processor
*/
val CE02: Cpu.Value = Value
/**
* The WDC 65816 processor
*/
val Sixteen: Cpu.Value = Value
/**
* The Intel 8080 processor
*/
val Intel8080: Cpu.Value = Value
/**
* The Intel 8085 processor
*/
val Intel8085: Cpu.Value = Value
/**
* The Intel 8085 processor, without illegal instructions
*/
val StrictIntel8085: Cpu.Value = Value
/**
* The Zilog Z80 processor
*/
val Z80: Cpu.Value = Value
/**
* The Zilog Z80 processor, without illegal instructions
*/
val StrictZ80: Cpu.Value = Value
/**
* The Zilog eZ80 processor
*/
val EZ80: Cpu.Value = Value
/**
* The Z80 core from the ZX Spectrum Next
*/
val Z80Next: Cpu.Value = Value
/**
* The Sharp LR35902 processor
*/
val Sharp: Cpu.Value = Value
/**
* The Intel 8086 or 8088 processor
*/
val Intel8086: Cpu.Value = Value
/**
* The Intel 80186 or 80188 processor
*/
val Intel80186: Cpu.Value = Value
/**
* The Motorola 6809 processor
*/
val Motorola6809: Cpu.Value = Value
/**
* Processors that can run code for WDC 65C02
*/
val CmosCompatible: Set[Cpu.Value] = Set(Cmos, HuC6280, CE02, Sixteen, SC02, Rockwell, Wdc)
/**
* Processors that can run code for Zilog Z80
*/
val Z80Compatible: Set[Cpu.Value] = Set(Z80, StrictZ80, EZ80, Z80Next)
/**
* Processors that can run code for Intel 8080
*/
val Intel8080Compatible: Set[Cpu.Value] = Set(Intel8080, Intel8085, StrictIntel8085, Z80, StrictZ80, EZ80, Z80Next)
/**
* Processors that can run code for Intel 8085
*/
val Intel8085Compatible: Set[Cpu.Value] = Set(Intel8085, StrictIntel8085)
import CompilationFlag._
private val alwaysDefaultFlags = Set(
VariableOverlap,
CompactReturnDispatchParams,
FunctionFallthrough,
RegisterVariables,
FunctionDeduplication,
EnableBreakpoints,
UseOptimizationHints,
GenericWarnings,
UselessCodeWarning,
BuggyCodeWarning,
FallbackValueUseWarning,
DeprecationWarning,
NonZeroTerminatedLiteralWarning,
CallToOverlappingBankWarning,
DataMissingInOutputWarning,
UnsupportedOptimizationHintWarning,
)
private val mosAlwaysDefaultFlags = alwaysDefaultFlags
private val i80AlwaysDefaultFlags = alwaysDefaultFlags
private val m6809AlwaysDefaultFlags = alwaysDefaultFlags
def defaultFlags(x: Cpu.Value): Set[CompilationFlag.Value] = x match {
case StrictMos =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, PreventJmpIndirectBug)
case Mos =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, PreventJmpIndirectBug)
case Ricoh =>
mosAlwaysDefaultFlags ++ Set(PreventJmpIndirectBug)
case StrictRicoh =>
mosAlwaysDefaultFlags ++ Set(PreventJmpIndirectBug)
case Cmos =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, EmitCmosOpcodes)
case SC02 =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, EmitCmosOpcodes, EmitSC02Opcodes)
case Rockwell =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, EmitCmosOpcodes, EmitSC02Opcodes, EmitRockwellOpcodes)
case Wdc =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, EmitCmosOpcodes, EmitSC02Opcodes, EmitRockwellOpcodes, EmitWdcOpcodes)
case HuC6280 =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, EmitCmosOpcodes, EmitSC02Opcodes, EmitRockwellOpcodes, EmitHudsonOpcodes)
case CE02 =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, EmitCmosOpcodes, EmitSC02Opcodes, EmitRockwellOpcodes, Emit65CE02Opcodes)
case Sixteen =>
mosAlwaysDefaultFlags ++ Set(DecimalMode, EmitCmosOpcodes, EmitSC02Opcodes, EmitEmulation65816Opcodes, EmitNative65816Opcodes, ReturnWordsViaAccumulator)
case Intel8080 =>
i80AlwaysDefaultFlags ++ Set(EmitIntel8080Opcodes, UseIntelSyntaxForInput, UseIntelSyntaxForOutput)
case StrictIntel8085 | Intel8085 =>
i80AlwaysDefaultFlags ++ Set(EmitIntel8080Opcodes, EmitIntel8085Opcodes, UseIntelSyntaxForInput, UseIntelSyntaxForOutput)
case StrictZ80 | Z80 =>
i80AlwaysDefaultFlags ++ Set(EmitIntel8080Opcodes, EmitExtended80Opcodes, EmitZ80Opcodes, UseIxForStack, UseShadowRegistersForInterrupts)
case Z80Next =>
i80AlwaysDefaultFlags ++ Set(EmitIntel8080Opcodes, EmitExtended80Opcodes, EmitZ80Opcodes, UseIxForStack, UseShadowRegistersForInterrupts, EmitIllegals, EmitZ80NextOpcodes)
case EZ80 =>
i80AlwaysDefaultFlags ++ Set(EmitIntel8080Opcodes, EmitExtended80Opcodes, EmitZ80Opcodes, UseIxForStack, UseShadowRegistersForInterrupts, EmitEZ80Opcodes)
case Sharp =>
i80AlwaysDefaultFlags ++ Set(EmitExtended80Opcodes, EmitSharpOpcodes)
case Intel8086 | Intel80186 =>
i80AlwaysDefaultFlags ++ Set(EmitIntel8080Opcodes, UseIxForStack, EmitIntel8085Opcodes, EmitIllegals)
case Motorola6809 =>
m6809AlwaysDefaultFlags
}
def fromString(name: String)(implicit log: Logger): Cpu.Value = name match {
case "nmos" => Mos
case "6502" => Mos
case "6510" => Mos
case "strict" => StrictMos
case "strictnmos" => StrictMos
case "strict6502" => StrictMos
case "strict6510" => StrictMos
case "cmos" => Cmos
case "65sc02" => SC02
case "sc02" => SC02
case "65c02" => Rockwell
case "c02" => Rockwell
case "w65c02" => Wdc
case "wdc65c02" => Wdc
case "wdc" => Wdc
case "hudson" => HuC6280
case "huc6280" => HuC6280
case "c6280" => HuC6280
case "6280" => HuC6280
case "65ce02" => CE02
case "ce02" => CE02
case "65816" => Sixteen
case "65c816" => Sixteen
case "816" => Sixteen
case "5a22" => Sixteen
case "ricoh" => Ricoh
case "2a03" => Ricoh
case "2a07" => Ricoh
case "strictricoh" => StrictRicoh
case "strict2a03" => StrictRicoh
case "strict2a07" => StrictRicoh
case "z80" => Z80
case "strictz80" => Z80
case "zx80next" => Z80Next
case "z80next" => Z80Next
// disabled for now:
// case "ez80" => EZ80
case "gameboy" => Sharp
case "gb" => Sharp
case "sharp" => Sharp
case "lr35902" => Sharp
case "8080" => Intel8080
case "i8080" => Intel8080
case "intel8080" => Intel8080
case "8085" => Intel8085
case "i8085" => Intel8085
case "intel8085" => Intel8085
case "strict8085" => StrictIntel8085
case "stricti8085" => StrictIntel8085
case "strictintel8085" => StrictIntel8085
case "intel8086" => Intel8086
case "i8086" => Intel8086
case "8086" => Intel8086
case "intel80186" => Intel80186
case "i80186" => Intel80186
case "80186" => Intel80186
case "intel80286" => Intel80186
case "i80286" => Intel80186
case "80286" => Intel80186
// undocumented for now
case "6809" => Motorola6809
case _ => log.fatal("Unknown CPU achitecture: " + name)
}
def getMaxSizeReturnableViaRegisters(cpu: Cpu.Value, compilationOptions: CompilationOptions): Int =
CpuFamily.forType(cpu) match {
case CpuFamily.M6502 => 2
case CpuFamily.I80 | CpuFamily.I86 => 4
case CpuFamily.M6809 => 2
case _ => ???
}
def isBigEndian(cpu: Cpu.Value): Boolean = CpuFamily.isBigEndian(CpuFamily.forType(cpu))
}
object CompilationFlag extends Enumeration {
val
// common compilation options:
EmitIllegals, DecimalMode, LenientTextEncoding, LineNumbersInAssembly, SourceInAssembly, EnableBreakpoints,
// compilation options for MOS:
EmitCmosOpcodes, EmitCmosNopOpcodes, EmitSC02Opcodes, EmitRockwellOpcodes, EmitWdcOpcodes, EmitHudsonOpcodes, Emit65CE02Opcodes, EmitEmulation65816Opcodes, EmitNative65816Opcodes,
PreventJmpIndirectBug, LargeCode, ReturnWordsViaAccumulator, SoftwareStack,
// compilation options for I80
EmitIntel8080Opcodes, EmitIntel8085Opcodes, EmitExtended80Opcodes, EmitZ80Opcodes, EmitEZ80Opcodes, EmitSharpOpcodes, EmitZ80NextOpcodes,
UseShadowRegistersForInterrupts,
UseIxForStack, UseIyForStack,
UseIxForScratch, UseIyForScratch,
UseIntelSyntaxForInput,
UseIntelSyntaxForOutput,
// compilation options for 6809
UseUForStack, UseYForStack,
// optimization options:
OptimizeForSize, OptimizeForSpeed, OptimizeForSonicSpeed, OptimizeForDebugging,
DangerousOptimizations, InlineFunctions, InterproceduralOptimization,
FunctionFallthrough, RegisterVariables, FunctionDeduplication, SubroutineExtraction,
OptimizeStdlib,
UseOptimizationHints,
// memory allocation options
VariableOverlap, CompactReturnDispatchParams, LUnixRelocatableCode,
// runtime check options
CheckIndexOutOfBounds,
// special options
SingleThreaded,
// warning options
GenericWarnings,
UselessCodeWarning,
BuggyCodeWarning,
DeprecationWarning,
FallbackValueUseWarning,
ExtraComparisonWarnings,
RorWarning,
NonZeroTerminatedLiteralWarning,
CallToOverlappingBankWarning,
DataMissingInOutputWarning,
UnsupportedOptimizationHintWarning,
FatalWarnings,
// special options for internal compiler use
EnableInternalTestSyntax,
InternalCurrentlyOptimizingForMeasurement = Value
val allWarnings: Set[CompilationFlag.Value] = Set(
GenericWarnings,
UselessCodeWarning,
BuggyCodeWarning,
DeprecationWarning,
FallbackValueUseWarning,
ExtraComparisonWarnings,
NonZeroTerminatedLiteralWarning,
CallToOverlappingBankWarning,
DataMissingInOutputWarning,
UnsupportedOptimizationHintWarning,
)
val fromString: Map[String, CompilationFlag.Value] = Map(
"lunix" -> LUnixRelocatableCode,
"emit_illegals" -> EmitIllegals,
"emit_cmos" -> EmitCmosOpcodes,
"emit_65sc02" -> EmitSC02Opcodes,
"emit_rockwell" -> EmitRockwellOpcodes,
"emit_wdc" -> EmitWdcOpcodes,
"emit_65ce02" -> Emit65CE02Opcodes,
"emit_huc6280" -> EmitHudsonOpcodes,
"emit_z80" -> EmitZ80Opcodes,
"emit_ez80" -> EmitEZ80Opcodes,
"emit_x80" -> EmitExtended80Opcodes,
"emit_8080" -> EmitIntel8080Opcodes,
"emit_8085" -> EmitIntel8085Opcodes,
"emit_sharp" -> EmitSharpOpcodes,
"ix_stack" -> UseIxForStack,
"iy_stack" -> UseIyForStack,
"ix_scratch" -> UseIxForScratch,
"iy_scratch" -> UseIyForScratch,
"u_stack" -> UseUForStack,
"y_stack" -> UseYForStack,
"software_stack" -> SoftwareStack,
"use_shadow_registers_for_irq" -> UseShadowRegistersForInterrupts,
"output_intel_syntax" -> UseIntelSyntaxForOutput,
"input_intel_syntax" -> UseIntelSyntaxForInput,
"ipo" -> InterproceduralOptimization,
"optimize_stdlib" -> OptimizeStdlib,
"function_fallthrough" -> FunctionFallthrough,
"function_deduplication" -> FunctionDeduplication,
"subroutine_extraction" -> SubroutineExtraction,
"inline" -> InlineFunctions,
"dangerous_optimizations" -> DangerousOptimizations,
"decimal_mode" -> DecimalMode,
"ror_warn" -> RorWarning,
"prevent_jmp_indirect_bug" -> PreventJmpIndirectBug,
"compact_dispatch_params" -> CompactReturnDispatchParams,
"lenient_encoding" -> LenientTextEncoding,
"breakpoints" -> EnableBreakpoints,
)
}