remove eval stack options

This commit is contained in:
Irmen de Jong 2023-07-15 11:05:25 +02:00
parent b3cb9b7fe2
commit 84925ab69c
28 changed files with 209 additions and 328 deletions

View File

@ -26,8 +26,6 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
PtMemMapped("P8ZP_SCRATCH_REG", DataType.UBYTE, options.compTarget.machine.zeropage.SCRATCH_REG, null, Position.DUMMY), PtMemMapped("P8ZP_SCRATCH_REG", DataType.UBYTE, options.compTarget.machine.zeropage.SCRATCH_REG, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W1", DataType.UWORD, options.compTarget.machine.zeropage.SCRATCH_W1, null, Position.DUMMY), PtMemMapped("P8ZP_SCRATCH_W1", DataType.UWORD, options.compTarget.machine.zeropage.SCRATCH_W1, null, Position.DUMMY),
PtMemMapped("P8ZP_SCRATCH_W2", DataType.UWORD, options.compTarget.machine.zeropage.SCRATCH_W2, null, Position.DUMMY), PtMemMapped("P8ZP_SCRATCH_W2", DataType.UWORD, options.compTarget.machine.zeropage.SCRATCH_W2, null, Position.DUMMY),
PtMemMapped("P8ESTACK_LO", DataType.ARRAY_UB, options.compTarget.machine.ESTACK_LO, 128u, Position.DUMMY),
PtMemMapped("P8ESTACK_HI", DataType.ARRAY_UB, options.compTarget.machine.ESTACK_HI, 128u, Position.DUMMY)
).forEach { ).forEach {
it.parent = program it.parent = program
st.add(StMemVar(it.name, it.type, it.address, it.arraySize?.toInt(), it)) st.add(StMemVar(it.name, it.type, it.address, it.arraySize?.toInt(), it))

View File

@ -13,7 +13,6 @@ class CompilationOptions(val output: OutputType,
val compTarget: ICompilationTarget, val compTarget: ICompilationTarget,
// these are set later, based on command line arguments or options in the source code: // these are set later, based on command line arguments or options in the source code:
var loadAddress: UInt, var loadAddress: UInt,
var slowCodegenWarnings: Boolean = false,
var optimize: Boolean = false, var optimize: Boolean = false,
var optimizeFloatExpressions: Boolean = false, var optimizeFloatExpressions: Boolean = false,
var asmQuiet: Boolean = false, var asmQuiet: Boolean = false,
@ -21,7 +20,6 @@ class CompilationOptions(val output: OutputType,
var experimentalCodegen: Boolean = false, var experimentalCodegen: Boolean = false,
var varsHighBank: Int? = null, var varsHighBank: Int? = null,
var splitWordArrays: Boolean = false, var splitWordArrays: Boolean = false,
var evalStackBaseAddress: UInt? = null,
var outputDir: Path = Path(""), var outputDir: Path = Path(""),
var symbolDefs: Map<String, String> = emptyMap() var symbolDefs: Map<String, String> = emptyMap()
) { ) {

View File

@ -13,8 +13,6 @@ interface IMachineDefinition {
val FLOAT_MAX_NEGATIVE: Double val FLOAT_MAX_NEGATIVE: Double
val FLOAT_MAX_POSITIVE: Double val FLOAT_MAX_POSITIVE: Double
val FLOAT_MEM_SIZE: Int val FLOAT_MEM_SIZE: Int
var ESTACK_LO: UInt
var ESTACK_HI: UInt
val PROGRAM_LOAD_ADDRESS : UInt val PROGRAM_LOAD_ADDRESS : UInt
val BSSHIGHRAM_START: UInt val BSSHIGHRAM_START: UInt
val BSSHIGHRAM_END: UInt val BSSHIGHRAM_END: UInt
@ -29,11 +27,4 @@ interface IMachineDefinition {
fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List<String> fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List<String>
fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path)
fun isIOAddress(address: UInt): Boolean fun isIOAddress(address: UInt): Boolean
fun overrideEvalStack(evalStackBaseAddress: UInt) {
require(evalStackBaseAddress and 255u == 0u)
ESTACK_LO = evalStackBaseAddress
ESTACK_HI = evalStackBaseAddress + 256u
require(ESTACK_LO !in golden.region && ESTACK_HI !in golden.region) { "user-set ESTACK can't be in GOLDEN ram" }
}
} }

View File

@ -13,10 +13,6 @@ class AtariMachineDefinition: IMachineDefinition {
override val FLOAT_MEM_SIZE = 6 override val FLOAT_MEM_SIZE = 6
override val PROGRAM_LOAD_ADDRESS = 0x2000u override val PROGRAM_LOAD_ADDRESS = 0x2000u
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
override var ESTACK_LO = 0x1b00u // $1b00-$1b7f inclusive // TODO
override var ESTACK_HI = 0x1b80u // $1b80-$1bff inclusive // TODO
override val BSSHIGHRAM_START = 0u // TODO override val BSSHIGHRAM_START = 0u // TODO
override val BSSHIGHRAM_END = 0u // TODO override val BSSHIGHRAM_END = 0u // TODO

View File

@ -15,10 +15,6 @@ class C128MachineDefinition: IMachineDefinition {
override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE
override val PROGRAM_LOAD_ADDRESS = 0x1c01u override val PROGRAM_LOAD_ADDRESS = 0x1c01u
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
override var ESTACK_LO = 0x1b00u // $1b00-$1b7f inclusive
override var ESTACK_HI = 0x1b80u // $1b80-$1bff inclusive
override val BSSHIGHRAM_START = 0u // TODO override val BSSHIGHRAM_START = 0u // TODO
override val BSSHIGHRAM_END = 0u // TODO override val BSSHIGHRAM_END = 0u // TODO

View File

@ -16,12 +16,8 @@ class C64MachineDefinition: IMachineDefinition {
override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE
override val PROGRAM_LOAD_ADDRESS = 0x0801u override val PROGRAM_LOAD_ADDRESS = 0x0801u
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
override var ESTACK_LO = 0xcf00u // $cf00-$cf7f inclusive
override var ESTACK_HI = 0xcf80u // $cf80-$cfff inclusive
override val BSSHIGHRAM_START = 0xc000u override val BSSHIGHRAM_START = 0xc000u
override val BSSHIGHRAM_END = ESTACK_LO override val BSSHIGHRAM_END = 0xd000u
override lateinit var zeropage: Zeropage override lateinit var zeropage: Zeropage
override lateinit var golden: GoldenRam override lateinit var golden: GoldenRam
@ -62,7 +58,7 @@ class C64MachineDefinition: IMachineDefinition {
override fun initializeMemoryAreas(compilerOptions: CompilationOptions) { override fun initializeMemoryAreas(compilerOptions: CompilationOptions) {
zeropage = C64Zeropage(compilerOptions) zeropage = C64Zeropage(compilerOptions)
golden = GoldenRam(compilerOptions, 0xc000u until ESTACK_LO) golden = GoldenRam(compilerOptions, 0xc000u until 0xd000u)
} }
} }

View File

@ -15,10 +15,6 @@ class CX16MachineDefinition: IMachineDefinition {
override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE override val FLOAT_MEM_SIZE = Mflpt5.FLOAT_MEM_SIZE
override val PROGRAM_LOAD_ADDRESS = 0x0801u override val PROGRAM_LOAD_ADDRESS = 0x0801u
// the 2*128 byte evaluation stack (1 page, on which bytes, words, and even floats are stored during calculations)
override var ESTACK_LO = 0x0700u // $0700-$077f inclusive
override var ESTACK_HI = 0x0780u // $0780-$07ff inclusive
override val BSSHIGHRAM_START = 0xa000u // hiram bank 1, 8Kb, assumed to be active override val BSSHIGHRAM_START = 0xa000u // hiram bank 1, 8Kb, assumed to be active
override val BSSHIGHRAM_END = 0xc000u // rom starts here. override val BSSHIGHRAM_END = 0xc000u // rom starts here.
@ -64,7 +60,7 @@ class CX16MachineDefinition: IMachineDefinition {
override fun initializeMemoryAreas(compilerOptions: CompilationOptions) { override fun initializeMemoryAreas(compilerOptions: CompilationOptions) {
zeropage = CX16Zeropage(compilerOptions) zeropage = CX16Zeropage(compilerOptions)
golden = GoldenRam(compilerOptions, 0x0400u until ESTACK_LO) golden = GoldenRam(compilerOptions, 0x0400u until 0x0800u)
} }
} }

View File

@ -15,8 +15,6 @@ class VirtualMachineDefinition: IMachineDefinition {
override val FLOAT_MEM_SIZE = 4 // 32-bits floating point override val FLOAT_MEM_SIZE = 4 // 32-bits floating point
override val PROGRAM_LOAD_ADDRESS = 0u // not actually used override val PROGRAM_LOAD_ADDRESS = 0u // not actually used
override var ESTACK_LO = 0u // not actually used
override var ESTACK_HI = 0u // not actually used
override val BSSHIGHRAM_START = 0u // not actually used override val BSSHIGHRAM_START = 0u // not actually used
override val BSSHIGHRAM_END = 0u // not actually used override val BSSHIGHRAM_END = 0u // not actually used
override lateinit var zeropage: Zeropage // not actually used override lateinit var zeropage: Zeropage // not actually used

View File

@ -581,10 +581,6 @@ class AsmGen6502Internal (
} }
} }
@Deprecated("avoid calling this as it generates slow evalstack based code")
internal fun translateExpression(expression: PtExpression) =
expressionsAsmGen.translateExpression(expression)
internal fun translateBuiltinFunctionCallExpression(bfc: PtBuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?): DataType? = internal fun translateBuiltinFunctionCallExpression(bfc: PtBuiltinFunctionCall, resultToStack: Boolean, resultRegister: RegisterOrPair?): DataType? =
builtinFunctionsAsmGen.translateFunctioncallExpression(bfc, resultToStack, resultRegister) builtinFunctionsAsmGen.translateFunctioncallExpression(bfc, resultToStack, resultRegister)
@ -625,7 +621,6 @@ class AsmGen6502Internal (
} }
internal fun assignExpressionTo(value: PtExpression, target: AsmAssignTarget) { internal fun assignExpressionTo(value: PtExpression, target: AsmAssignTarget) {
// don't use translateExpression() to avoid evalstack
when (target.datatype) { when (target.datatype) {
in ByteDatatypes -> { in ByteDatatypes -> {
assignExpressionToRegister(value, RegisterOrPair.A) assignExpressionToRegister(value, RegisterOrPair.A)

View File

@ -8,11 +8,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
private val asmgen: AsmGen6502Internal, private val asmgen: AsmGen6502Internal,
private val allocator: VariableAllocator) { private val allocator: VariableAllocator) {
@Deprecated("avoid calling this as it generates slow evalstack based code") private fun translateExpressionSTACK(expression: PtExpression) {
internal fun translateExpression(expression: PtExpression) {
if (this.asmgen.options.slowCodegenWarnings) {
asmgen.errors.warn("slow stack evaluation used for expression", expression.position)
}
translateExpressionInternal(expression) translateExpressionInternal(expression)
} }

View File

@ -75,8 +75,6 @@ internal class ProgramAndVarsGen(
asmgen.out("P8ZP_SCRATCH_W1 = ${zp.SCRATCH_W1} ; word") asmgen.out("P8ZP_SCRATCH_W1 = ${zp.SCRATCH_W1} ; word")
asmgen.out("P8ZP_SCRATCH_W2 = ${zp.SCRATCH_W2} ; word") asmgen.out("P8ZP_SCRATCH_W2 = ${zp.SCRATCH_W2} ; word")
asmgen.out(".weak") // hack to allow user to override the following two with command line redefinition (however, just use '-esa' command line option instead!) asmgen.out(".weak") // hack to allow user to override the following two with command line redefinition (however, just use '-esa' command line option instead!)
asmgen.out("P8ESTACK_LO = ${compTarget.machine.ESTACK_LO.toHex()}")
asmgen.out("P8ESTACK_HI = ${compTarget.machine.ESTACK_HI.toHex()}")
asmgen.out(".endweak") asmgen.out(".endweak")
if(options.symbolDefs.isNotEmpty()) { if(options.symbolDefs.isNotEmpty()) {

View File

@ -174,10 +174,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
SourceStorageKind.REGISTER -> { SourceStorageKind.REGISTER -> {
asmgen.assignRegister(assign.source.register!!, assign.target) asmgen.assignRegister(assign.source.register!!, assign.target)
} }
SourceStorageKind.STACK -> {
if(assign.target.kind!=TargetStorageKind.STACK || assign.target.datatype != assign.source.datatype)
assignStackValue(assign.target)
}
} }
} }
@ -313,10 +309,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
is PtBinaryExpression -> { is PtBinaryExpression -> {
if(!attemptAssignOptimizedBinexpr(value, assign)) { if(!attemptAssignOptimizedBinexpr(value, assign)) {
// All remaining binary expressions just evaluate via the stack for now. // TOO BAD: the expression was too complex to translate into assembly.
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here, throw AssemblyError("Expression is too complex to translate into assembly. Split it up into several separate statements, introduce a temporary variable, or otherwise rewrite it. Location: ${assign.position}")
// because the code here is the implementation of exactly that...)
fallbackToStackEval(assign)
} }
} }
else -> throw AssemblyError("weird assignment value type $value") else -> throw AssemblyError("weird assignment value type $value")
@ -1215,15 +1209,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
} }
private fun fallbackToStackEval(assign: AsmAssignment) {
// this routine is called for assigning a binaryexpression value that has no optimized code path.
asmgen.translateExpression(assign.source.expression!!)
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
asmgen.signExtendStackLsb(assign.source.datatype)
if (assign.target.kind != TargetStorageKind.STACK || assign.target.datatype != assign.source.datatype)
assignStackValue(assign.target)
}
private fun containmentCheckIntoA(containment: PtContainmentCheck) { private fun containmentCheckIntoA(containment: PtContainmentCheck) {
val elementDt = containment.element.type val elementDt = containment.element.type
val symbol = asmgen.symbolTable.lookup(containment.iterable.name) val symbol = asmgen.symbolTable.lookup(containment.iterable.name)

View File

@ -96,8 +96,6 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
} }
private fun fallbackAssign(origAssign: PtAugmentedAssign): IRCodeChunks { private fun fallbackAssign(origAssign: PtAugmentedAssign): IRCodeChunks {
if (codeGen.options.slowCodegenWarnings)
codeGen.errors.warn("indirect code for in-place assignment", origAssign.position)
val value: PtExpression val value: PtExpression
if(origAssign.operator in PrefixOperators) { if(origAssign.operator in PrefixOperators) {
value = PtPrefix(origAssign.operator, origAssign.value.type, origAssign.value.position) value = PtPrefix(origAssign.operator, origAssign.value.type, origAssign.value.position)

View File

@ -29,9 +29,6 @@ class IRCodeGen(
irSymbolTable = IRSymbolTable(symbolTable) irSymbolTable = IRSymbolTable(symbolTable)
val irProg = IRProgram(program.name, irSymbolTable, options, program.encoding) val irProg = IRProgram(program.name, irSymbolTable, options, program.encoding)
if(options.evalStackBaseAddress!=null)
throw AssemblyError("IR doesn't use eval-stack")
// collect global variables initializers // collect global variables initializers
program.allBlocks().forEach { program.allBlocks().forEach {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()

View File

@ -111,8 +111,6 @@ class StatementOptimizer(private val program: Program,
// remove obvious dangling elses (else after a return) // remove obvious dangling elses (else after a return)
if(ifElse.elsepart.isNotEmpty() && ifElse.truepart.statements.singleOrNull() is Return) { if(ifElse.elsepart.isNotEmpty() && ifElse.truepart.statements.singleOrNull() is Return) {
val elsePart = AnonymousScope(ifElse.elsepart.statements, ifElse.elsepart.position) val elsePart = AnonymousScope(ifElse.elsepart.statements, ifElse.elsepart.position)
if(options.slowCodegenWarnings)
errors.warn("else can be omitted", ifElse.elsepart.position)
return listOf( return listOf(
IAstModification.ReplaceNode(ifElse.elsepart, AnonymousScope(mutableListOf(), ifElse.elsepart.position), ifElse), IAstModification.ReplaceNode(ifElse.elsepart, AnonymousScope(mutableListOf(), ifElse.elsepart.position), ifElse),
IAstModification.InsertAfter(ifElse, elsePart, parent as IStatementContainer) IAstModification.InsertAfter(ifElse, elsePart, parent as IStatementContainer)

View File

@ -775,110 +775,107 @@ cx16 {
; they are simulated on the C128 as well but their location in memory is different ; they are simulated on the C128 as well but their location in memory is different
; (because there's no room for them in the zeropage) ; (because there's no room for them in the zeropage)
; $1300-$1bff is unused RAM on C128. We'll use $1a00-$1bff as the lo/hi evalstack. ; $1300-$1bff is unused RAM on C128. We'll use $1a00-$1bff as the lo/hi evalstack.
; the virtual registers are allocated at the bottom of the eval-stack (should be ample space unless &uword r0 = $1be0
; you're doing insane nesting of expressions...) &uword r1 = $1be2
; NOTE: the memory location of these registers can change based on the "-esa" compiler option &uword r2 = $1be4
&uword r0 = $1b00 &uword r3 = $1be6
&uword r1 = $1b02 &uword r4 = $1be8
&uword r2 = $1b04 &uword r5 = $1bea
&uword r3 = $1b06 &uword r6 = $1bec
&uword r4 = $1b08 &uword r7 = $1bee
&uword r5 = $1b0a &uword r8 = $1bf0
&uword r6 = $1b0c &uword r9 = $1bf2
&uword r7 = $1b0e &uword r10 = $1bf4
&uword r8 = $1b10 &uword r11 = $1bf6
&uword r9 = $1b12 &uword r12 = $1bf8
&uword r10 = $1b14 &uword r13 = $1bfa
&uword r11 = $1b16 &uword r14 = $1bfc
&uword r12 = $1b18 &uword r15 = $1bfe
&uword r13 = $1b1a
&uword r14 = $1b1c
&uword r15 = $1b1e
&word r0s = $1b00 &word r0s = $1be0
&word r1s = $1b02 &word r1s = $1be2
&word r2s = $1b04 &word r2s = $1be4
&word r3s = $1b06 &word r3s = $1be6
&word r4s = $1b08 &word r4s = $1be8
&word r5s = $1b0a &word r5s = $1bea
&word r6s = $1b0c &word r6s = $1bec
&word r7s = $1b0e &word r7s = $1bee
&word r8s = $1b10 &word r8s = $1bf0
&word r9s = $1b12 &word r9s = $1bf2
&word r10s = $1b14 &word r10s = $1bf4
&word r11s = $1b16 &word r11s = $1bf6
&word r12s = $1b18 &word r12s = $1bf8
&word r13s = $1b1a &word r13s = $1bfa
&word r14s = $1b1c &word r14s = $1bfc
&word r15s = $1b1e &word r15s = $1bfe
&ubyte r0L = $1b00 &ubyte r0L = $1be0
&ubyte r1L = $1b02 &ubyte r1L = $1be2
&ubyte r2L = $1b04 &ubyte r2L = $1be4
&ubyte r3L = $1b06 &ubyte r3L = $1be6
&ubyte r4L = $1b08 &ubyte r4L = $1be8
&ubyte r5L = $1b0a &ubyte r5L = $1bea
&ubyte r6L = $1b0c &ubyte r6L = $1bec
&ubyte r7L = $1b0e &ubyte r7L = $1bee
&ubyte r8L = $1b10 &ubyte r8L = $1bf0
&ubyte r9L = $1b12 &ubyte r9L = $1bf2
&ubyte r10L = $1b14 &ubyte r10L = $1bf4
&ubyte r11L = $1b16 &ubyte r11L = $1bf6
&ubyte r12L = $1b18 &ubyte r12L = $1bf8
&ubyte r13L = $1b1a &ubyte r13L = $1bfa
&ubyte r14L = $1b1c &ubyte r14L = $1bfc
&ubyte r15L = $1b1e &ubyte r15L = $1bfe
&ubyte r0H = $1b01 &ubyte r0H = $1be1
&ubyte r1H = $1b03 &ubyte r1H = $1be3
&ubyte r2H = $1b05 &ubyte r2H = $1be5
&ubyte r3H = $1b07 &ubyte r3H = $1be7
&ubyte r4H = $1b09 &ubyte r4H = $1be9
&ubyte r5H = $1b0b &ubyte r5H = $1beb
&ubyte r6H = $1b0d &ubyte r6H = $1bed
&ubyte r7H = $1b0f &ubyte r7H = $1bef
&ubyte r8H = $1b11 &ubyte r8H = $1bf1
&ubyte r9H = $1b13 &ubyte r9H = $1bf3
&ubyte r10H = $1b15 &ubyte r10H = $1bf5
&ubyte r11H = $1b17 &ubyte r11H = $1bf7
&ubyte r12H = $1b19 &ubyte r12H = $1bf9
&ubyte r13H = $1b1b &ubyte r13H = $1bfb
&ubyte r14H = $1b1d &ubyte r14H = $1bfd
&ubyte r15H = $1b1f &ubyte r15H = $1bff
&byte r0sL = $1b00 &byte r0sL = $1be0
&byte r1sL = $1b02 &byte r1sL = $1be2
&byte r2sL = $1b04 &byte r2sL = $1be4
&byte r3sL = $1b06 &byte r3sL = $1be6
&byte r4sL = $1b08 &byte r4sL = $1be8
&byte r5sL = $1b0a &byte r5sL = $1bea
&byte r6sL = $1b0c &byte r6sL = $1bec
&byte r7sL = $1b0e &byte r7sL = $1bee
&byte r8sL = $1b10 &byte r8sL = $1bf0
&byte r9sL = $1b12 &byte r9sL = $1bf2
&byte r10sL = $1b14 &byte r10sL = $1bf4
&byte r11sL = $1b16 &byte r11sL = $1bf6
&byte r12sL = $1b18 &byte r12sL = $1bf8
&byte r13sL = $1b1a &byte r13sL = $1bfa
&byte r14sL = $1b1c &byte r14sL = $1bfc
&byte r15sL = $1b1e &byte r15sL = $1bfe
&byte r0sH = $1b01 &byte r0sH = $1be1
&byte r1sH = $1b03 &byte r1sH = $1be3
&byte r2sH = $1b05 &byte r2sH = $1be5
&byte r3sH = $1b07 &byte r3sH = $1be7
&byte r4sH = $1b09 &byte r4sH = $1be9
&byte r5sH = $1b0b &byte r5sH = $1beb
&byte r6sH = $1b0d &byte r6sH = $1bed
&byte r7sH = $1b0f &byte r7sH = $1bef
&byte r8sH = $1b11 &byte r8sH = $1bf1
&byte r9sH = $1b13 &byte r9sH = $1bf3
&byte r10sH = $1b15 &byte r10sH = $1bf5
&byte r11sH = $1b17 &byte r11sH = $1bf7
&byte r12sH = $1b19 &byte r12sH = $1bf9
&byte r13sH = $1b1b &byte r13sH = $1bfb
&byte r14sH = $1b1d &byte r14sH = $1bfd
&byte r15sH = $1b1f &byte r15sH = $1bff
asmsub save_virtual_registers() clobbers(A,Y) { asmsub save_virtual_registers() clobbers(A,Y) {
%asm {{ %asm {{

View File

@ -742,111 +742,110 @@ cx16 {
; the sixteen virtual 16-bit registers that the CX16 has defined in the zeropage ; the sixteen virtual 16-bit registers that the CX16 has defined in the zeropage
; they are simulated on the C64 as well but their location in memory is different ; they are simulated on the C64 as well but their location in memory is different
; (because there's no room for them in the zeropage) ; (because there's no room for them in the zeropage in the default configuration)
; they are allocated at the bottom of the eval-stack (should be ample space unless ; Note that when using ZP options that free up more of the zeropage (such as %zeropage kernalsafe)
; you're doing insane nesting of expressions...) ; there might be enough space to put them there after all, and the compiler will change these addresses!
; NOTE: the memory location of these registers can change based on the "-esa" compiler option &uword r0 = $cfe0
&uword r0 = $cf00 &uword r1 = $cfe2
&uword r1 = $cf02 &uword r2 = $cfe4
&uword r2 = $cf04 &uword r3 = $cfe6
&uword r3 = $cf06 &uword r4 = $cfe8
&uword r4 = $cf08 &uword r5 = $cfea
&uword r5 = $cf0a &uword r6 = $cfec
&uword r6 = $cf0c &uword r7 = $cfee
&uword r7 = $cf0e &uword r8 = $cff0
&uword r8 = $cf10 &uword r9 = $cff2
&uword r9 = $cf12 &uword r10 = $cff4
&uword r10 = $cf14 &uword r11 = $cff6
&uword r11 = $cf16 &uword r12 = $cff8
&uword r12 = $cf18 &uword r13 = $cffa
&uword r13 = $cf1a &uword r14 = $cffc
&uword r14 = $cf1c &uword r15 = $cffe
&uword r15 = $cf1e
&word r0s = $cf00 &word r0s = $cfe0
&word r1s = $cf02 &word r1s = $cfe2
&word r2s = $cf04 &word r2s = $cfe4
&word r3s = $cf06 &word r3s = $cfe6
&word r4s = $cf08 &word r4s = $cfe8
&word r5s = $cf0a &word r5s = $cfea
&word r6s = $cf0c &word r6s = $cfec
&word r7s = $cf0e &word r7s = $cfee
&word r8s = $cf10 &word r8s = $cff0
&word r9s = $cf12 &word r9s = $cff2
&word r10s = $cf14 &word r10s = $cff4
&word r11s = $cf16 &word r11s = $cff6
&word r12s = $cf18 &word r12s = $cff8
&word r13s = $cf1a &word r13s = $cffa
&word r14s = $cf1c &word r14s = $cffc
&word r15s = $cf1e &word r15s = $cffe
&ubyte r0L = $cf00 &ubyte r0L = $cfe0
&ubyte r1L = $cf02 &ubyte r1L = $cfe2
&ubyte r2L = $cf04 &ubyte r2L = $cfe4
&ubyte r3L = $cf06 &ubyte r3L = $cfe6
&ubyte r4L = $cf08 &ubyte r4L = $cfe8
&ubyte r5L = $cf0a &ubyte r5L = $cfea
&ubyte r6L = $cf0c &ubyte r6L = $cfec
&ubyte r7L = $cf0e &ubyte r7L = $cfee
&ubyte r8L = $cf10 &ubyte r8L = $cff0
&ubyte r9L = $cf12 &ubyte r9L = $cff2
&ubyte r10L = $cf14 &ubyte r10L = $cff4
&ubyte r11L = $cf16 &ubyte r11L = $cff6
&ubyte r12L = $cf18 &ubyte r12L = $cff8
&ubyte r13L = $cf1a &ubyte r13L = $cffa
&ubyte r14L = $cf1c &ubyte r14L = $cffc
&ubyte r15L = $cf1e &ubyte r15L = $cffe
&ubyte r0H = $cf01 &ubyte r0H = $cfe1
&ubyte r1H = $cf03 &ubyte r1H = $cfe3
&ubyte r2H = $cf05 &ubyte r2H = $cfe5
&ubyte r3H = $cf07 &ubyte r3H = $cfe7
&ubyte r4H = $cf09 &ubyte r4H = $cfe9
&ubyte r5H = $cf0b &ubyte r5H = $cfeb
&ubyte r6H = $cf0d &ubyte r6H = $cfed
&ubyte r7H = $cf0f &ubyte r7H = $cfef
&ubyte r8H = $cf11 &ubyte r8H = $cff1
&ubyte r9H = $cf13 &ubyte r9H = $cff3
&ubyte r10H = $cf15 &ubyte r10H = $cff5
&ubyte r11H = $cf17 &ubyte r11H = $cff7
&ubyte r12H = $cf19 &ubyte r12H = $cff9
&ubyte r13H = $cf1b &ubyte r13H = $cffb
&ubyte r14H = $cf1d &ubyte r14H = $cffd
&ubyte r15H = $cf1f &ubyte r15H = $cfff
&byte r0sL = $cf00 &byte r0sL = $cfe0
&byte r1sL = $cf02 &byte r1sL = $cfe2
&byte r2sL = $cf04 &byte r2sL = $cfe4
&byte r3sL = $cf06 &byte r3sL = $cfe6
&byte r4sL = $cf08 &byte r4sL = $cfe8
&byte r5sL = $cf0a &byte r5sL = $cfea
&byte r6sL = $cf0c &byte r6sL = $cfec
&byte r7sL = $cf0e &byte r7sL = $cfee
&byte r8sL = $cf10 &byte r8sL = $cff0
&byte r9sL = $cf12 &byte r9sL = $cff2
&byte r10sL = $cf14 &byte r10sL = $cff4
&byte r11sL = $cf16 &byte r11sL = $cff6
&byte r12sL = $cf18 &byte r12sL = $cff8
&byte r13sL = $cf1a &byte r13sL = $cffa
&byte r14sL = $cf1c &byte r14sL = $cffc
&byte r15sL = $cf1e &byte r15sL = $cffe
&byte r0sH = $cf01 &byte r0sH = $cfe1
&byte r1sH = $cf03 &byte r1sH = $cfe3
&byte r2sH = $cf05 &byte r2sH = $cfe5
&byte r3sH = $cf07 &byte r3sH = $cfe7
&byte r4sH = $cf09 &byte r4sH = $cfe9
&byte r5sH = $cf0b &byte r5sH = $cfeb
&byte r6sH = $cf0d &byte r6sH = $cfed
&byte r7sH = $cf0f &byte r7sH = $cfef
&byte r8sH = $cf11 &byte r8sH = $cff1
&byte r9sH = $cf13 &byte r9sH = $cff3
&byte r10sH = $cf15 &byte r10sH = $cff5
&byte r11sH = $cf17 &byte r11sH = $cff7
&byte r12sH = $cf19 &byte r12sH = $cff9
&byte r13sH = $cf1b &byte r13sH = $cffb
&byte r14sH = $cf1d &byte r14sH = $cffd
&byte r15sH = $cf1f &byte r15sH = $cfff
asmsub save_virtual_registers() clobbers(A,Y) { asmsub save_virtual_registers() clobbers(A,Y) {
%asm {{ %asm {{

View File

@ -3,7 +3,6 @@ package prog8
import kotlinx.cli.* import kotlinx.cli.*
import prog8.ast.base.AstException import prog8.ast.base.AstException
import prog8.code.core.CbmPrgLauncherType import prog8.code.core.CbmPrgLauncherType
import prog8.code.core.toHex
import prog8.code.target.* import prog8.code.target.*
import prog8.code.target.virtual.VirtualMachineDefinition import prog8.code.target.virtual.VirtualMachineDefinition
import prog8.compiler.CompilationResult import prog8.compiler.CompilationResult
@ -39,7 +38,6 @@ private fun compileMain(args: Array<String>): Boolean {
val cli = ArgParser("prog8compiler", prefixStyle = ArgParser.OptionPrefixStyle.JVM) val cli = ArgParser("prog8compiler", prefixStyle = ArgParser.OptionPrefixStyle.JVM)
val asmListfile by cli.option(ArgType.Boolean, fullName = "asmlist", description = "make the assembler produce a listing file as well") val asmListfile by cli.option(ArgType.Boolean, fullName = "asmlist", description = "make the assembler produce a listing file as well")
val symbolDefs by cli.option(ArgType.String, fullName = "D", description = "define assembly symbol(s) with -D SYMBOL=VALUE").multiple() val symbolDefs by cli.option(ArgType.String, fullName = "D", description = "define assembly symbol(s) with -D SYMBOL=VALUE").multiple()
val evalStackAddrString by cli.option(ArgType.String, fullName = "esa", description = "override the eval-stack base address (must be page aligned)")
val startEmulator1 by cli.option(ArgType.Boolean, fullName = "emu", description = "auto-start emulator after successful compilation") val startEmulator1 by cli.option(ArgType.Boolean, fullName = "emu", description = "auto-start emulator after successful compilation")
val startEmulator2 by cli.option(ArgType.Boolean, fullName = "emu2", description = "auto-start alternative emulator after successful compilation") val startEmulator2 by cli.option(ArgType.Boolean, fullName = "emu2", description = "auto-start alternative emulator after successful compilation")
val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental/alternative codegen") val experimentalCodegen by cli.option(ArgType.Boolean, fullName = "expericodegen", description = "use experimental/alternative codegen")
@ -48,7 +46,6 @@ private fun compileMain(args: Array<String>): Boolean {
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".") val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
val optimizeFloatExpressions by cli.option(ArgType.Boolean, fullName = "optfloatx", description = "optimize float expressions (warning: can increase program size)") val optimizeFloatExpressions by cli.option(ArgType.Boolean, fullName = "optfloatx", description = "optimize float expressions (warning: can increase program size)")
val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results") val quietAssembler by cli.option(ArgType.Boolean, fullName = "quietasm", description = "don't print assembler output results")
val slowCodegenWarnings by cli.option(ArgType.Boolean, fullName = "slowwarn", description="show debug warnings about slow/problematic assembly code generation")
val sourceDirs by cli.option(ArgType.String, fullName="srcdirs", description = "list of extra paths, separated with ${File.pathSeparator}, to search in for imported modules").multiple().delimiter(File.pathSeparator) val sourceDirs by cli.option(ArgType.String, fullName="srcdirs", description = "list of extra paths, separated with ${File.pathSeparator}, to search in for imported modules").multiple().delimiter(File.pathSeparator)
val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler (one of '${C64Target.NAME}', '${C128Target.NAME}', '${Cx16Target.NAME}', '${AtariTarget.NAME}', '${VMTarget.NAME}') (required)") val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler (one of '${C64Target.NAME}', '${C128Target.NAME}', '${Cx16Target.NAME}', '${AtariTarget.NAME}', '${VMTarget.NAME}') (required)")
val startVm by cli.option(ArgType.Boolean, fullName = "vm", description = "load and run a .p8ir IR source file in the VM") val startVm by cli.option(ArgType.Boolean, fullName = "vm", description = "load and run a .p8ir IR source file in the VM")
@ -101,25 +98,6 @@ private fun compileMain(args: Array<String>): Boolean {
return runVm(moduleFiles.first()) return runVm(moduleFiles.first())
} }
var evalStackAddr: UInt? = null
if(evalStackAddrString!=null) {
try {
evalStackAddr = if (evalStackAddrString!!.startsWith("0x"))
evalStackAddrString!!.substring(2).toUInt(16)
else if (evalStackAddrString!!.startsWith("$"))
evalStackAddrString!!.substring(1).toUInt(16)
else
evalStackAddrString!!.toUInt()
} catch(nx: NumberFormatException) {
System.err.println("invalid address for evalstack: $evalStackAddrString")
return false
}
if(evalStackAddr !in 256u..65536u-512u || (evalStackAddr and 255u != 0u)) {
System.err.println("invalid address for evalstack: ${evalStackAddr.toHex()}")
return false
}
}
val processedSymbols = processSymbolDefs(symbolDefs) ?: return false val processedSymbols = processSymbolDefs(symbolDefs) ?: return false
if(watchMode==true) { if(watchMode==true) {
@ -136,13 +114,11 @@ private fun compileMain(args: Array<String>): Boolean {
dontOptimize != true, dontOptimize != true,
optimizeFloatExpressions == true, optimizeFloatExpressions == true,
dontWriteAssembly != true, dontWriteAssembly != true,
slowCodegenWarnings == true,
quietAssembler == true, quietAssembler == true,
asmListfile == true, asmListfile == true,
experimentalCodegen == true, experimentalCodegen == true,
varsHighBank, varsHighBank,
compilationTarget!!, compilationTarget!!,
evalStackAddr,
splitWordArrays == true, splitWordArrays == true,
processedSymbols, processedSymbols,
srcdirs, srcdirs,
@ -205,13 +181,11 @@ private fun compileMain(args: Array<String>): Boolean {
dontOptimize != true, dontOptimize != true,
optimizeFloatExpressions == true, optimizeFloatExpressions == true,
dontWriteAssembly != true, dontWriteAssembly != true,
slowCodegenWarnings == true,
quietAssembler == true, quietAssembler == true,
asmListfile == true, asmListfile == true,
experimentalCodegen == true, experimentalCodegen == true,
varsHighBank, varsHighBank,
compilationTarget!!, compilationTarget!!,
evalStackAddr,
splitWordArrays == true, splitWordArrays == true,
processedSymbols, processedSymbols,
srcdirs, srcdirs,

View File

@ -31,13 +31,11 @@ class CompilerArguments(val filepath: Path,
val optimize: Boolean, val optimize: Boolean,
val optimizeFloatExpressions: Boolean, val optimizeFloatExpressions: Boolean,
val writeAssembly: Boolean, val writeAssembly: Boolean,
val slowCodegenWarnings: Boolean,
val quietAssembler: Boolean, val quietAssembler: Boolean,
val asmListfile: Boolean, val asmListfile: Boolean,
val experimentalCodegen: Boolean, val experimentalCodegen: Boolean,
val varsHighBank: Int?, val varsHighBank: Int?,
val compilationTarget: String, val compilationTarget: String,
val evalStackBaseAddress: UInt?,
val splitWordArrays: Boolean, val splitWordArrays: Boolean,
val symbolDefs: Map<String, String>, val symbolDefs: Map<String, String>,
val sourceDirs: List<String> = emptyList(), val sourceDirs: List<String> = emptyList(),
@ -70,14 +68,12 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
compilationOptions = options compilationOptions = options
with(compilationOptions) { with(compilationOptions) {
slowCodegenWarnings = args.slowCodegenWarnings
optimize = args.optimize optimize = args.optimize
optimizeFloatExpressions = optimizeFloatExpr optimizeFloatExpressions = optimizeFloatExpr
asmQuiet = args.quietAssembler asmQuiet = args.quietAssembler
asmListfile = args.asmListfile asmListfile = args.asmListfile
experimentalCodegen = args.experimentalCodegen experimentalCodegen = args.experimentalCodegen
varsHighBank = args.varsHighBank varsHighBank = args.varsHighBank
evalStackBaseAddress = args.evalStackBaseAddress
splitWordArrays = args.splitWordArrays splitWordArrays = args.splitWordArrays
outputDir = args.outputDir.normalize() outputDir = args.outputDir.normalize()
symbolDefs = args.symbolDefs symbolDefs = args.symbolDefs
@ -85,10 +81,6 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
program = programresult program = programresult
importedFiles = imported importedFiles = imported
if(compilationOptions.evalStackBaseAddress!=null) {
compTarget.machine.overrideEvalStack(compilationOptions.evalStackBaseAddress!!)
}
processAst(program, args.errors, compilationOptions) processAst(program, args.errors, compilationOptions)
if (compilationOptions.optimize) { if (compilationOptions.optimize) {
// println("*********** COMPILER AST RIGHT BEFORE OPTIMIZING *************") // println("*********** COMPILER AST RIGHT BEFORE OPTIMIZING *************")

View File

@ -9,8 +9,6 @@ import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification import prog8.ast.walk.IAstModification
import prog8.code.core.* import prog8.code.core.*
import prog8.code.target.C64Target import prog8.code.target.C64Target
import prog8.code.target.Cx16Target
import prog8.code.target.VMTarget
class AstPreprocessor(val program: Program, class AstPreprocessor(val program: Program,
@ -25,9 +23,6 @@ class AstPreprocessor(val program: Program,
relocateCx16VirtualRegisters(program, 0x0004u) relocateCx16VirtualRegisters(program, 0x0004u)
} }
} }
else if(options.compTarget.name !in setOf(Cx16Target.NAME, VMTarget.NAME)) {
relocateCx16VirtualRegisters(program, options.compTarget.machine.ESTACK_HI)
}
return noModifications return noModifications
} }

View File

@ -28,13 +28,11 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat
optimize, optimize,
optimizeFloatExpressions = true, optimizeFloatExpressions = true,
writeAssembly = true, writeAssembly = true,
slowCodegenWarnings = false,
quietAssembler = true, quietAssembler = true,
asmListfile = false, asmListfile = false,
experimentalCodegen = false, experimentalCodegen = false,
varsHighBank = null, varsHighBank = null,
compilationTarget = target.name, compilationTarget = target.name,
evalStackBaseAddress = null,
splitWordArrays = false, splitWordArrays = false,
symbolDefs = emptyMap(), symbolDefs = emptyMap(),
outputDir = outputDir outputDir = outputDir

View File

@ -45,13 +45,11 @@ class TestCompilerOptionSourcedirs: FunSpec({
optimize = false, optimize = false,
optimizeFloatExpressions = false, optimizeFloatExpressions = false,
writeAssembly = true, writeAssembly = true,
slowCodegenWarnings = false,
quietAssembler = true, quietAssembler = true,
asmListfile = false, asmListfile = false,
experimentalCodegen = false, experimentalCodegen = false,
varsHighBank = null, varsHighBank = null,
compilationTarget = Cx16Target.NAME, compilationTarget = Cx16Target.NAME,
evalStackBaseAddress = null,
splitWordArrays = false, splitWordArrays = false,
symbolDefs = emptyMap(), symbolDefs = emptyMap(),
sourceDirs, sourceDirs,

View File

@ -26,13 +26,11 @@ internal fun compileFile(
optimize, optimize,
optimizeFloatExpressions = optFloatExpr, optimizeFloatExpressions = optFloatExpr,
writeAssembly = writeAssembly, writeAssembly = writeAssembly,
slowCodegenWarnings = false,
quietAssembler = true, quietAssembler = true,
asmListfile = false, asmListfile = false,
experimentalCodegen = false, experimentalCodegen = false,
varsHighBank = null, varsHighBank = null,
platform.name, platform.name,
evalStackBaseAddress = null,
symbolDefs = emptyMap(), symbolDefs = emptyMap(),
outputDir = outputDir, outputDir = outputDir,
errors = errors ?: ErrorReporterForTests(), errors = errors ?: ErrorReporterForTests(),

View File

@ -3,15 +3,16 @@
main main
{ {
; 00f9
sub start() sub start()
{ {
ubyte a=1 word bb
ubyte b=2
ubyte c=3
ubyte d=4
ubyte xx = (a*b)+(c*d)
xx++
when bb {
0,1,22 -> bb+=10
33,44,55 -> bb+=20
42345 -> bb+=99
else -> bb+=30
}
} }
} }

View File

@ -35,9 +35,7 @@ class RequestParser : Take {
optimize = true, optimize = true,
optimizeFloatExpressions = false, optimizeFloatExpressions = false,
writeAssembly = true, writeAssembly = true,
slowCodegenWarnings = true,
compilationTarget = "c64", compilationTarget = "c64",
evalStackBaseAddress = null,
symbolDefs = emptyMap(), symbolDefs = emptyMap(),
quietAssembler = false, quietAssembler = false,
asmListfile = false, asmListfile = false,

View File

@ -88,7 +88,6 @@ class IRFileReader {
val zpReserved = mutableListOf<UIntRange>() val zpReserved = mutableListOf<UIntRange>()
var loadAddress = target.machine.PROGRAM_LOAD_ADDRESS var loadAddress = target.machine.PROGRAM_LOAD_ADDRESS
var optimize = true var optimize = true
var evalStackBaseAddress: UInt? = null
var outputDir = Path("") var outputDir = Path("")
if(text.isNotBlank()) { if(text.isNotBlank()) {
@ -109,7 +108,6 @@ class IRFileReader {
"launcher" -> launcher = CbmPrgLauncherType.valueOf(value) "launcher" -> launcher = CbmPrgLauncherType.valueOf(value)
"zeropage" -> zeropage = ZeropageType.valueOf(value) "zeropage" -> zeropage = ZeropageType.valueOf(value)
"loadAddress" -> loadAddress = parseIRValue(value).toUInt() "loadAddress" -> loadAddress = parseIRValue(value).toUInt()
"evalStackBaseAddress" -> evalStackBaseAddress = if(value=="") null else parseIRValue(value).toUInt()
"zpReserved" -> { "zpReserved" -> {
val (zpstart, zpend) = value.split(',') val (zpstart, zpend) = value.split(',')
zpReserved.add(UIntRange(zpstart.toUInt(), zpend.toUInt())) zpReserved.add(UIntRange(zpstart.toUInt(), zpend.toUInt()))
@ -130,7 +128,6 @@ class IRFileReader {
false, false,
target, target,
loadAddress, loadAddress,
evalStackBaseAddress = evalStackBaseAddress,
outputDir = outputDir, outputDir = outputDir,
optimize = optimize optimize = optimize
) )

View File

@ -171,7 +171,6 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
} }
xml.writeCharacters("loadAddress=${irProgram.options.loadAddress.toHex()}\n") xml.writeCharacters("loadAddress=${irProgram.options.loadAddress.toHex()}\n")
xml.writeCharacters("optimize=${irProgram.options.optimize}\n") xml.writeCharacters("optimize=${irProgram.options.optimize}\n")
xml.writeCharacters("evalStackBaseAddress=${irProgram.options.evalStackBaseAddress?.toHex() ?: ""}\n")
xml.writeCharacters("outputDir=${irProgram.options.outputDir.toAbsolutePath()}\n") xml.writeCharacters("outputDir=${irProgram.options.outputDir.toAbsolutePath()}\n")
// other options not yet useful here? // other options not yet useful here?
xml.writeEndElement() xml.writeEndElement()

View File

@ -48,7 +48,6 @@ output=PRG
launcher=BASIC launcher=BASIC
zeropage=KERNALSAFE zeropage=KERNALSAFE
loadAddress=$0000 loadAddress=$0000
evalStackBaseAddress=
</OPTIONS> </OPTIONS>
<ASMSYMBOLS> <ASMSYMBOLS>