optimize isZpVar

This commit is contained in:
Irmen de Jong 2023-02-16 00:33:37 +01:00
parent 5c3f41f64d
commit c59df6ec20
10 changed files with 86 additions and 89 deletions

View File

@ -11,7 +11,7 @@ class MemAllocationError(message: String) : Exception(message)
abstract class MemoryAllocator(protected val options: CompilationOptions) {
data class VarAllocation(val address: UInt, val dt: DataType, val size: Int)
abstract fun allocate(name: List<String>,
abstract fun allocate(name: String,
datatype: DataType,
numElements: Int?,
position: Position?,
@ -29,7 +29,7 @@ abstract class Zeropage(options: CompilationOptions): MemoryAllocator(options) {
// the variables allocated into Zeropage.
// name (scoped) ==> pair of address to (Datatype + bytesize)
val allocatedVariables = mutableMapOf<List<String>, VarAllocation>()
val allocatedVariables = mutableMapOf<String, VarAllocation>()
val free = mutableListOf<UInt>() // subclasses must set this to the appropriate free locations.
@ -51,7 +51,7 @@ abstract class Zeropage(options: CompilationOptions): MemoryAllocator(options) {
return free.windowed(2).any { it[0] == it[1] - 1u }
}
override fun allocate(name: List<String>,
override fun allocate(name: String,
datatype: DataType,
numElements: Int?,
position: Position?,
@ -107,7 +107,7 @@ abstract class Zeropage(options: CompilationOptions): MemoryAllocator(options) {
private fun reserve(range: UIntRange) = free.removeAll(range)
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: List<String>): UInt {
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: String): UInt {
require(size>=0)
free.removeAll(address until address+size.toUInt())
if(name.isNotEmpty()) {
@ -135,7 +135,7 @@ class GoldenRam(options: CompilationOptions, val region: UIntRange): MemoryAlloc
private var nextLocation: UInt = region.first
override fun allocate(
name: List<String>,
name: String,
datatype: DataType,
numElements: Int?,
position: Position?,

View File

@ -83,12 +83,12 @@ class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
// The base addres is $04. Unfortunately it cannot be the same as on the Commander X16 ($02).
for(reg in 0..15) {
allocatedVariables[listOf("cx16", "r${reg}")] = VarAllocation((4+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
allocatedVariables[listOf("cx16", "r${reg}s")] = VarAllocation((4+reg*2).toUInt(), DataType.WORD, 2) // cx16.r0s .. cx16.r15s
allocatedVariables[listOf("cx16", "r${reg}L")] = VarAllocation((4+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0L .. cx16.r15L
allocatedVariables[listOf("cx16", "r${reg}H")] = VarAllocation((5+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0H .. cx16.r15H
allocatedVariables[listOf("cx16", "r${reg}sL")] = VarAllocation((4+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables[listOf("cx16", "r${reg}sH")] = VarAllocation((5+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
allocatedVariables["cx16.r${reg}"] = VarAllocation((4+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = VarAllocation((4+reg*2).toUInt(), DataType.WORD, 2) // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = VarAllocation((4+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = VarAllocation((5+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = VarAllocation((4+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = VarAllocation((5+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
free.remove((4+reg*2).toUInt())
free.remove((5+reg*2).toUInt())
}

View File

@ -58,12 +58,12 @@ class CX16Zeropage(options: CompilationOptions) : Zeropage(options) {
// However, to be able for the compiler to "see" them as zero page variables, we have to register them here as well.
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
for(reg in 0..15) {
allocatedVariables[listOf("cx16", "r${reg}")] = VarAllocation((2+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
allocatedVariables[listOf("cx16", "r${reg}s")] = VarAllocation((2+reg*2).toUInt(), DataType.WORD, 2) // cx16.r0s .. cx16.r15s
allocatedVariables[listOf("cx16", "r${reg}L")] = VarAllocation((2+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0L .. cx16.r15L
allocatedVariables[listOf("cx16", "r${reg}H")] = VarAllocation((3+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0H .. cx16.r15H
allocatedVariables[listOf("cx16", "r${reg}sL")] = VarAllocation((2+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables[listOf("cx16", "r${reg}sH")] = VarAllocation((3+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
allocatedVariables["cx16.r${reg}"] = VarAllocation((2+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
allocatedVariables["cx16.r${reg}s"] = VarAllocation((2+reg*2).toUInt(), DataType.WORD, 2) // cx16.r0s .. cx16.r15s
allocatedVariables["cx16.r${reg}L"] = VarAllocation((2+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0L .. cx16.r15L
allocatedVariables["cx16.r${reg}H"] = VarAllocation((3+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0H .. cx16.r15H
allocatedVariables["cx16.r${reg}sL"] = VarAllocation((2+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sL .. cx16.r15sL
allocatedVariables["cx16.r${reg}sH"] = VarAllocation((3+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
}
}
}

View File

@ -148,7 +148,7 @@ class AsmGen6502Internal (
is PtVariable, is PtMemMapped -> {
val sourceName = asmVariableName(pointervar)
if (isTargetCpu(CpuType.CPU65c02)) {
return if (allocator.isZpVar((target as PtNamedNode).scopedName.split('.'))) {
return if (allocator.isZpVar((target as PtNamedNode).scopedName)) {
// pointervar is already in the zero page, no need to copy
out(" lda ($sourceName)")
sourceName
@ -162,7 +162,7 @@ class AsmGen6502Internal (
"P8ZP_SCRATCH_W1"
}
} else {
return if (allocator.isZpVar((target as PtNamedNode).scopedName.split('.'))) {
return if (allocator.isZpVar((target as PtNamedNode).scopedName)) {
// pointervar is already in the zero page, no need to copy
out(" ldy #0 | lda ($sourceName),y")
sourceName
@ -185,7 +185,7 @@ class AsmGen6502Internal (
internal fun storeAIntoPointerVar(pointervar: PtIdentifier) {
val sourceName = asmVariableName(pointervar)
if (isTargetCpu(CpuType.CPU65c02)) {
if (allocator.isZpVar(pointervar.name.split('.'))) {
if (allocator.isZpVar(pointervar.name)) {
// pointervar is already in the zero page, no need to copy
out(" sta ($sourceName)")
} else {
@ -197,7 +197,7 @@ class AsmGen6502Internal (
sta (P8ZP_SCRATCH_W2)""")
}
} else {
if (allocator.isZpVar(pointervar.name.split('.'))) {
if (allocator.isZpVar(pointervar.name)) {
// pointervar is already in the zero page, no need to copy
out(" ldy #0 | sta ($sourceName),y")
} else {
@ -747,7 +747,7 @@ $repeatLabel lda $counterVar
val counterVar = makeLabel("counter")
when(dt) {
DataType.UBYTE, DataType.UWORD -> {
val result = zeropage.allocate(listOf(counterVar), dt, null, stmt.position, errors)
val result = zeropage.allocate(counterVar, dt, null, stmt.position, errors)
result.fold(
success = { (address, _) -> asmInfo.extraVars.add(Triple(dt, counterVar, address)) },
failure = { asmInfo.extraVars.add(Triple(dt, counterVar, null)) } // allocate normally
@ -963,7 +963,7 @@ $repeatLabel lda $counterVar
}
}
internal fun isZpVar(variable: PtIdentifier): Boolean = allocator.isZpVar(variable.name.split('.'))
internal fun isZpVar(variable: PtIdentifier): Boolean = allocator.isZpVar(variable.name)
internal fun jmp(asmLabel: String, indirect: Boolean=false) {
if(indirect) {

View File

@ -289,7 +289,7 @@ $loopLabel sty $indexVar
}
if(numElements>=16u) {
// allocate index var on ZP if possible
val result = zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors)
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
result.fold(
success = { (address,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
failure = { asmgen.out("$indexVar .byte 0") }
@ -330,7 +330,7 @@ $loopLabel sty $indexVar
}
if(length>=16u) {
// allocate index var on ZP if possible
val result = zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors)
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
result.fold(
success = { (address,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
failure = { asmgen.out("$indexVar .byte 0") }

View File

@ -236,7 +236,7 @@ internal class ProgramAndVarsGen(
// normal statically allocated variables
val variables = varsInBlock
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName.split('.')) }
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName) }
.map { it.value as StStaticVariable }
nonZpVariables2asm(variables)
}
@ -354,7 +354,7 @@ internal class ProgramAndVarsGen(
// normal statically allocated variables
val variables = varsInSubroutine
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName.split('.')) }
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName) }
.map { it.value as StStaticVariable }
nonZpVariables2asm(variables)
@ -439,7 +439,7 @@ internal class ProgramAndVarsGen(
val result = mutableListOf<ZpStringWithInitial>()
val vars = allocator.zeropageVars.filter { it.value.dt==DataType.STR }
for (variable in vars) {
val scopedName = variable.key.joinToString(".")
val scopedName = variable.key
val svar = symboltable.flat.getValue(scopedName) as StStaticVariable
if(svar.onetimeInitializationStringValue!=null)
result.add(ZpStringWithInitial(scopedName, variable.value, svar.onetimeInitializationStringValue!!))
@ -451,7 +451,7 @@ internal class ProgramAndVarsGen(
val result = mutableListOf<ZpArrayWithInitial>()
val vars = allocator.zeropageVars.filter { it.value.dt in ArrayDatatypes }
for (variable in vars) {
val scopedName = variable.key.joinToString(".")
val scopedName = variable.key
val svar = symboltable.flat.getValue(scopedName) as StStaticVariable
if(svar.onetimeInitializationArrayValue!=null)
result.add(ZpArrayWithInitial(scopedName, variable.value, svar.onetimeInitializationArrayValue!!))
@ -460,12 +460,11 @@ internal class ProgramAndVarsGen(
}
private fun zeropagevars2asm(varNames: Set<String>) {
val namesLists = varNames.map { it.split('.') }.toSet()
val zpVariables = allocator.zeropageVars.filter { it.key in namesLists }.toList().sortedBy { it.second.address }
val zpVariables = allocator.zeropageVars.filter { it.key in varNames }.toList().sortedBy { it.second.address }
for ((scopedName, zpvar) in zpVariables) {
if (scopedName.size == 2 && scopedName[0] == "cx16" && scopedName[1][0] == 'r' && scopedName[1][1].isDigit())
if (scopedName.startsWith("cx16.r"))
continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped
asmgen.out("${scopedName.last()} \t= ${zpvar.address} \t; zp ${zpvar.dt}")
asmgen.out("${scopedName.substringAfterLast('.')} \t= ${zpvar.address} \t; zp ${zpvar.dt}")
}
}

View File

@ -16,13 +16,14 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
private val zeropage = options.compTarget.machine.zeropage
internal val globalFloatConsts = mutableMapOf<Double, String>() // all float values in the entire program (value -> varname)
internal val zeropageVars: Map<List<String>, MemoryAllocator.VarAllocation> = zeropage.allocatedVariables
internal val zeropageVars: Map<String, MemoryAllocator.VarAllocation>
init {
allocateZeropageVariables()
zeropageVars = zeropage.allocatedVariables
}
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropageVars // TODO as dotted string instead of list
internal fun isZpVar(scopedName: String) = scopedName in zeropageVars
internal fun getFloatAsmConst(number: Double): String {
val asmName = globalFloatConsts[number]
@ -56,7 +57,7 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
varsRequiringZp.forEach { variable ->
val result = zeropage.allocate(
variable.scopedName.split('.'),
variable.scopedName,
variable.dt,
variable.length,
variable.astNode.position,
@ -75,7 +76,7 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
if(errors.noErrors()) {
varsPreferringZp.forEach { variable ->
val result = zeropage.allocate(
variable.scopedName.split('.'),
variable.scopedName,
variable.dt,
variable.length,
variable.astNode.position,
@ -95,7 +96,7 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
break
} else {
val result = zeropage.allocate(
variable.scopedName.split('.'),
variable.scopedName,
variable.dt,
variable.length,
variable.astNode.position,

View File

@ -25,7 +25,7 @@ class TestGoldenRam: FunSpec({
test("empty golden ram allocations") {
val errors = ErrorReporterForTests()
val golden = GoldenRam(options, UIntRange.EMPTY)
val result = golden.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
val result = golden.allocate("test", DataType.UBYTE, null, null, errors)
result.expectError { "should not be able to allocate anything" }
}
@ -33,28 +33,28 @@ class TestGoldenRam: FunSpec({
val errors = ErrorReporterForTests()
val golden = GoldenRam(options, 0x400u until 0x800u)
var result = golden.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
var result = golden.allocate("test", DataType.UBYTE, null, null, errors)
var alloc = result.getOrThrow()
alloc.size shouldBe 1
alloc.address shouldBe 0x400u
result = golden.allocate(listOf("test"), DataType.STR, 100, null, errors)
result = golden.allocate("test", DataType.STR, 100, null, errors)
alloc = result.getOrThrow()
alloc.size shouldBe 100
alloc.address shouldBe 0x401u
repeat(461) {
result = golden.allocate(listOf("test"), DataType.UWORD, null, null, errors)
result = golden.allocate("test", DataType.UWORD, null, null, errors)
alloc = result.getOrThrow()
alloc.size shouldBe 2
}
result = golden.allocate(listOf("test"), DataType.UWORD, null, null, errors)
result = golden.allocate("test", DataType.UWORD, null, null, errors)
result.expectError { "just 1 more byte available" }
result = golden.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
result = golden.allocate("test", DataType.UBYTE, null, null, errors)
alloc = result.getOrThrow()
alloc.size shouldBe 1
alloc.address shouldBe golden.region.last
result = golden.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
result = golden.allocate("test", DataType.UBYTE, null, null, errors)
result.expectError { "nothing more available" }
}

View File

@ -71,26 +71,26 @@ class TestC64Zeropage: FunSpec({
compTarget = c64target, loadAddress = 999u
))
var result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
var result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
result = zp.allocate(listOf("varname"), DataType.UBYTE, null, null, errors)
result = zp.allocate("varname", DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
shouldThrow<IllegalArgumentException> { zp.allocate(listOf("varname"), DataType.UBYTE,null, null, errors) }
result = zp.allocate(listOf("varname2"), DataType.UBYTE, null, null, errors)
shouldThrow<IllegalArgumentException> { zp.allocate("varname", DataType.UBYTE,null, null, errors) }
result = zp.allocate("varname2", DataType.UBYTE, null, null, errors)
result.onFailure { fail(it.toString()) }
}
test("testZpFloatEnable") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target, 999u))
var result = zp.allocate(emptyList(), DataType.FLOAT, null, null, errors)
var result = zp.allocate("", DataType.FLOAT, null, null, errors)
result.expectError { "should be allocation error due to disabled floats" }
val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, false, c64target, 999u))
result = zp2.allocate(emptyList(), DataType.FLOAT, null, null, errors)
result = zp2.allocate("", DataType.FLOAT, null, null, errors)
result.expectError { "should be allocation error due to disabled ZP use" }
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, c64target, 999u))
zp3.allocate(emptyList(), DataType.FLOAT, null, null, errors)
zp3.allocate("", DataType.FLOAT, null, null, errors)
}
test("testZpModesWithFloats") {
@ -112,7 +112,7 @@ class TestC64Zeropage: FunSpec({
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, false, c64target, 999u))
println(zp.free)
zp.availableBytes() shouldBe 0
val result = zp.allocate(emptyList(), DataType.BYTE, null, null, errors)
val result = zp.allocate("", DataType.BYTE, null, null, errors)
result.expectError { "expected error due to disabled ZP use" }
}
@ -125,9 +125,9 @@ class TestC64Zeropage: FunSpec({
zp3.availableBytes() shouldBe 97
val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target, 999u))
zp4.availableBytes() shouldBe 207
zp4.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
zp4.allocate("test", DataType.UBYTE, null, null, errors)
zp4.availableBytes() shouldBe 206
zp4.allocate(listOf("test2"), DataType.UBYTE, null, null, errors)
zp4.allocate("test2", DataType.UBYTE, null, null, errors)
zp4.availableBytes() shouldBe 205
}
@ -166,19 +166,19 @@ class TestC64Zeropage: FunSpec({
zp.hasByteAvailable() shouldBe true
zp.hasWordAvailable() shouldBe true
var result = zp.allocate(emptyList(), DataType.FLOAT, null, null, errors)
var result = zp.allocate("", DataType.FLOAT, null, null, errors)
result.expectError { "expect allocation error: in regular zp there aren't 5 sequential bytes free" }
for (i in 0 until zp.availableBytes()) {
val alloc = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
val alloc = zp.allocate("", DataType.UBYTE, null, null, errors)
alloc.getOrElse { throw it }
}
zp.availableBytes() shouldBe 0
zp.hasByteAvailable() shouldBe false
zp.hasWordAvailable() shouldBe false
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.expectError { "expected allocation error" }
result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
result = zp.allocate("", DataType.UWORD, null, null, errors)
result.expectError { "expected allocation error" }
}
@ -187,47 +187,47 @@ class TestC64Zeropage: FunSpec({
zp.availableBytes() shouldBe 207
zp.hasByteAvailable() shouldBe true
zp.hasWordAvailable() shouldBe true
var result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
var result = zp.allocate("", DataType.UWORD, null, null, errors)
val loc = result.getOrElse { throw it } .address
loc shouldBeGreaterThan 3u
loc shouldNotBeIn zp.free
val num = zp.availableBytes() / 2
for(i in 0..num-3) {
zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
zp.allocate("", DataType.UWORD, null, null, errors)
}
zp.availableBytes() shouldBe 5
// can't allocate because no more sequential bytes, only fragmented
result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
result = zp.allocate("", DataType.UWORD, null, null, errors)
result.expectError { "should give allocation error" }
for(i in 0..4) {
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
zp.allocate("", DataType.UBYTE, null, null, errors)
}
zp.availableBytes() shouldBe 0
zp.hasByteAvailable() shouldBe false
zp.hasWordAvailable() shouldBe false
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
result = zp.allocate("", DataType.UBYTE, null, null, errors)
result.expectError { "should give allocation error" }
}
test("testEfficientAllocation") {
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target, 999u))
zp.availableBytes() shouldBe 18
zp.allocate(emptyList(), DataType.WORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x04u
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x06u
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x0au
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x9bu
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x9eu
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0xa5u
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0xb0u
zp.allocate(emptyList(), DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0xbeu
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x0eu
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x92u
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x96u
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0xf9u
zp.allocate("", DataType.WORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x04u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x06u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x0au
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x9bu
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x9eu
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0xa5u
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0xb0u
zp.allocate("", DataType.UWORD, null, null, errors).getOrElse{throw it}.address shouldBe 0xbeu
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x0eu
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x92u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0x96u
zp.allocate("", DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0xf9u
zp.availableBytes() shouldBe 0
}
@ -258,9 +258,9 @@ class TestCx16Zeropage: FunSpec({
zp2.availableBytes() shouldBe 175
val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target, 999u))
zp3.availableBytes() shouldBe 216
zp3.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
zp3.allocate("test", DataType.UBYTE, null, null, errors)
zp3.availableBytes() shouldBe 215
zp3.allocate(listOf("test2"), DataType.UBYTE, null, null, errors)
zp3.allocate("test2", DataType.UBYTE, null, null, errors)
zp3.availableBytes() shouldBe 214
}
@ -276,12 +276,12 @@ class TestCx16Zeropage: FunSpec({
test("preallocated zp vars") {
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target, 999u))
zp1.allocatedVariables[listOf("test")] shouldBe null
zp1.allocatedVariables[listOf("cx16", "r0")] shouldNotBe null
zp1.allocatedVariables[listOf("cx16", "r15")] shouldNotBe null
zp1.allocatedVariables[listOf("cx16", "r0L")] shouldNotBe null
zp1.allocatedVariables[listOf("cx16", "r15L")] shouldNotBe null
zp1.allocatedVariables[listOf("cx16", "r0sH")] shouldNotBe null
zp1.allocatedVariables[listOf("cx16", "r15sH")] shouldNotBe null
zp1.allocatedVariables["test"] shouldBe null
zp1.allocatedVariables["cx16.r0"] shouldNotBe null
zp1.allocatedVariables["cx16.r15"] shouldNotBe null
zp1.allocatedVariables["cx16.r0L"] shouldNotBe null
zp1.allocatedVariables["cx16.r15L"] shouldNotBe null
zp1.allocatedVariables["cx16.r0sH"] shouldNotBe null
zp1.allocatedVariables["cx16.r15sH"] shouldNotBe null
}
})

View File

@ -17,9 +17,6 @@ For 9.0 major changes
- OR.... make all this more generic and use some %segment option to create real segments for 64tass?
- (need separate step in codegen and IR to write the "golden" variables)
- rewrite 6502 codegen on Pt* ast and symboltable, instead of CompilerAst nodes.
- optimize "dotted string" comments again.
Need help with
^^^^^^^^^^^^^^