mirror of
https://github.com/irmen/prog8.git
synced 2025-01-24 06:30:24 +00:00
less joins
This commit is contained in:
parent
c25eb088ec
commit
3718b9d768
@ -11,7 +11,7 @@ class MemAllocationError(message: String) : Exception(message)
|
|||||||
abstract class MemoryAllocator(protected val options: CompilationOptions) {
|
abstract class MemoryAllocator(protected val options: CompilationOptions) {
|
||||||
data class VarAllocation(val address: UInt, val dt: DataType, val size: Int)
|
data class VarAllocation(val address: UInt, val dt: DataType, val size: Int)
|
||||||
|
|
||||||
abstract fun allocate(name: String,
|
abstract fun allocate(name: List<String>,
|
||||||
datatype: DataType,
|
datatype: DataType,
|
||||||
numElements: Int?,
|
numElements: Int?,
|
||||||
position: Position?,
|
position: Position?,
|
||||||
@ -29,7 +29,7 @@ abstract class Zeropage(options: CompilationOptions): MemoryAllocator(options) {
|
|||||||
|
|
||||||
// the variables allocated into Zeropage.
|
// the variables allocated into Zeropage.
|
||||||
// name (scoped) ==> pair of address to (Datatype + bytesize)
|
// name (scoped) ==> pair of address to (Datatype + bytesize)
|
||||||
val allocatedVariables = mutableMapOf<String, VarAllocation>()
|
val allocatedVariables = mutableMapOf<List<String>, VarAllocation>()
|
||||||
|
|
||||||
val free = mutableListOf<UInt>() // subclasses must set this to the appropriate free locations.
|
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 }
|
return free.windowed(2).any { it[0] == it[1] - 1u }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun allocate(name: String,
|
override fun allocate(name: List<String>,
|
||||||
datatype: DataType,
|
datatype: DataType,
|
||||||
numElements: Int?,
|
numElements: Int?,
|
||||||
position: Position?,
|
position: Position?,
|
||||||
@ -107,7 +107,7 @@ abstract class Zeropage(options: CompilationOptions): MemoryAllocator(options) {
|
|||||||
|
|
||||||
private fun reserve(range: UIntRange) = free.removeAll(range)
|
private fun reserve(range: UIntRange) = free.removeAll(range)
|
||||||
|
|
||||||
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: String): UInt {
|
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: List<String>): UInt {
|
||||||
require(size>=0)
|
require(size>=0)
|
||||||
free.removeAll(address until address+size.toUInt())
|
free.removeAll(address until address+size.toUInt())
|
||||||
if(name.isNotEmpty()) {
|
if(name.isNotEmpty()) {
|
||||||
@ -135,7 +135,7 @@ class GoldenRam(options: CompilationOptions, val region: UIntRange): MemoryAlloc
|
|||||||
private var nextLocation: UInt = region.first
|
private var nextLocation: UInt = region.first
|
||||||
|
|
||||||
override fun allocate(
|
override fun allocate(
|
||||||
name: String,
|
name: List<String>,
|
||||||
datatype: DataType,
|
datatype: DataType,
|
||||||
numElements: Int?,
|
numElements: Int?,
|
||||||
position: Position?,
|
position: Position?,
|
||||||
|
@ -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)
|
// 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).
|
// The base addres is $04. Unfortunately it cannot be the same as on the Commander X16 ($02).
|
||||||
for(reg in 0..15) {
|
for(reg in 0..15) {
|
||||||
allocatedVariables["cx16.r${reg}"] = VarAllocation((4+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
|
allocatedVariables[listOf("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[listOf("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[listOf("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[listOf("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[listOf("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
|
allocatedVariables[listOf("cx16", "r${reg}sH")] = VarAllocation((5+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
|
||||||
free.remove((4+reg*2).toUInt())
|
free.remove((4+reg*2).toUInt())
|
||||||
free.remove((5+reg*2).toUInt())
|
free.remove((5+reg*2).toUInt())
|
||||||
}
|
}
|
||||||
|
@ -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.
|
// 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)
|
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
|
||||||
for(reg in 0..15) {
|
for(reg in 0..15) {
|
||||||
allocatedVariables["cx16.r${reg}"] = VarAllocation((2+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
|
allocatedVariables[listOf("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[listOf("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[listOf("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[listOf("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[listOf("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
|
allocatedVariables[listOf("cx16", "r${reg}sH")] = VarAllocation((3+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -100,12 +100,12 @@ class AsmGen(internal val program: Program,
|
|||||||
fun asmSymbolName(identifier: IdentifierReference) = asmSymbolName(identifier.nameInSource)
|
fun asmSymbolName(identifier: IdentifierReference) = asmSymbolName(identifier.nameInSource)
|
||||||
fun asmVariableName(identifier: IdentifierReference) = asmVariableName(identifier.nameInSource)
|
fun asmVariableName(identifier: IdentifierReference) = asmVariableName(identifier.nameInSource)
|
||||||
|
|
||||||
internal fun getTempVarName(dt: DataType): List<String> {
|
internal fun getTempVarName(dt: DataType): String {
|
||||||
return when(dt) {
|
return when(dt) {
|
||||||
DataType.UBYTE -> listOf("cx16", "r9L")
|
DataType.UBYTE -> "cx16.r9L"
|
||||||
DataType.BYTE -> listOf("cx16", "r9sL")
|
DataType.BYTE -> "cx16.r9sL"
|
||||||
DataType.UWORD -> listOf("cx16", "r9")
|
DataType.UWORD -> "cx16.r9"
|
||||||
DataType.WORD -> listOf("cx16", "r9s")
|
DataType.WORD -> "cx16.r9s"
|
||||||
DataType.FLOAT -> TODO("no temporary float var available")
|
DataType.FLOAT -> TODO("no temporary float var available")
|
||||||
else -> throw FatalAstException("invalid dt $dt")
|
else -> throw FatalAstException("invalid dt $dt")
|
||||||
}
|
}
|
||||||
@ -123,7 +123,7 @@ class AsmGen(internal val program: Program,
|
|||||||
is VarDecl -> {
|
is VarDecl -> {
|
||||||
val sourceName = asmVariableName(pointervar)
|
val sourceName = asmVariableName(pointervar)
|
||||||
if (isTargetCpu(CpuType.CPU65c02)) {
|
if (isTargetCpu(CpuType.CPU65c02)) {
|
||||||
return if (allocator.isZpVar(target.scopedName.joinToString("."))) {
|
return if (allocator.isZpVar(target.scopedName)) {
|
||||||
// pointervar is already in the zero page, no need to copy
|
// pointervar is already in the zero page, no need to copy
|
||||||
out(" lda ($sourceName)")
|
out(" lda ($sourceName)")
|
||||||
sourceName
|
sourceName
|
||||||
@ -137,7 +137,7 @@ class AsmGen(internal val program: Program,
|
|||||||
"P8ZP_SCRATCH_W1"
|
"P8ZP_SCRATCH_W1"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return if (allocator.isZpVar(target.scopedName.joinToString("."))) {
|
return if (allocator.isZpVar(target.scopedName)) {
|
||||||
// pointervar is already in the zero page, no need to copy
|
// pointervar is already in the zero page, no need to copy
|
||||||
out(" ldy #0 | lda ($sourceName),y")
|
out(" ldy #0 | lda ($sourceName),y")
|
||||||
sourceName
|
sourceName
|
||||||
@ -161,7 +161,7 @@ class AsmGen(internal val program: Program,
|
|||||||
val sourceName = asmVariableName(pointervar)
|
val sourceName = asmVariableName(pointervar)
|
||||||
val vardecl = pointervar.targetVarDecl(program)!!
|
val vardecl = pointervar.targetVarDecl(program)!!
|
||||||
if (isTargetCpu(CpuType.CPU65c02)) {
|
if (isTargetCpu(CpuType.CPU65c02)) {
|
||||||
if (allocator.isZpVar(vardecl.scopedName.joinToString("."))) {
|
if (allocator.isZpVar(vardecl.scopedName)) {
|
||||||
// pointervar is already in the zero page, no need to copy
|
// pointervar is already in the zero page, no need to copy
|
||||||
out(" sta ($sourceName)")
|
out(" sta ($sourceName)")
|
||||||
} else {
|
} else {
|
||||||
@ -173,7 +173,7 @@ class AsmGen(internal val program: Program,
|
|||||||
sta (P8ZP_SCRATCH_W2)""")
|
sta (P8ZP_SCRATCH_W2)""")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (allocator.isZpVar(vardecl.scopedName.joinToString("."))) {
|
if (allocator.isZpVar(vardecl.scopedName)) {
|
||||||
// pointervar is already in the zero page, no need to copy
|
// pointervar is already in the zero page, no need to copy
|
||||||
out(" ldy #0 | sta ($sourceName),y")
|
out(" ldy #0 | sta ($sourceName),y")
|
||||||
} else {
|
} else {
|
||||||
@ -726,7 +726,7 @@ $repeatLabel lda $counterVar
|
|||||||
val counterVar = program.makeLabel("counter")
|
val counterVar = program.makeLabel("counter")
|
||||||
when(dt) {
|
when(dt) {
|
||||||
DataType.UBYTE, DataType.UWORD -> {
|
DataType.UBYTE, DataType.UWORD -> {
|
||||||
val result = zeropage.allocate(counterVar, dt, null, stmt.position, errors)
|
val result = zeropage.allocate(listOf(counterVar), dt, null, stmt.position, errors)
|
||||||
result.fold(
|
result.fold(
|
||||||
success = { (address, _) -> asmInfo.extraVars.add(Triple(dt, counterVar, address)) },
|
success = { (address, _) -> asmInfo.extraVars.add(Triple(dt, counterVar, address)) },
|
||||||
failure = { asmInfo.extraVars.add(Triple(dt, counterVar, null)) } // allocate normally
|
failure = { asmInfo.extraVars.add(Triple(dt, counterVar, null)) } // allocate normally
|
||||||
@ -988,7 +988,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun isZpVar(variable: IdentifierReference): Boolean =
|
internal fun isZpVar(variable: IdentifierReference): Boolean =
|
||||||
allocator.isZpVar(variable.targetVarDecl(program)!!.scopedName.joinToString("."))
|
allocator.isZpVar(variable.targetVarDecl(program)!!.scopedName)
|
||||||
|
|
||||||
internal fun jmp(asmLabel: String, indirect: Boolean=false) {
|
internal fun jmp(asmLabel: String, indirect: Boolean=false) {
|
||||||
if(indirect) {
|
if(indirect) {
|
||||||
|
@ -287,7 +287,7 @@ $loopLabel sty $indexVar
|
|||||||
}
|
}
|
||||||
if(length>=16) {
|
if(length>=16) {
|
||||||
// allocate index var on ZP if possible
|
// allocate index var on ZP if possible
|
||||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
val result = zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||||
result.fold(
|
result.fold(
|
||||||
success = { (address,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
success = { (address,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
||||||
failure = { asmgen.out("$indexVar .byte 0") }
|
failure = { asmgen.out("$indexVar .byte 0") }
|
||||||
@ -328,7 +328,7 @@ $loopLabel sty $indexVar
|
|||||||
}
|
}
|
||||||
if(length>=16) {
|
if(length>=16) {
|
||||||
// allocate index var on ZP if possible
|
// allocate index var on ZP if possible
|
||||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
val result = zeropage.allocate(listOf(indexVar), DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||||
result.fold(
|
result.fold(
|
||||||
success = { (address,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
success = { (address,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
||||||
failure = { asmgen.out("$indexVar .byte 0") }
|
failure = { asmgen.out("$indexVar .byte 0") }
|
||||||
|
@ -242,7 +242,7 @@ internal class ProgramAndVarsGen(
|
|||||||
|
|
||||||
// normal statically allocated variables
|
// normal statically allocated variables
|
||||||
val variables = varsInBlock
|
val variables = varsInBlock
|
||||||
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName) }
|
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName.split('.')) }
|
||||||
.map { it.value as StStaticVariable }
|
.map { it.value as StStaticVariable }
|
||||||
nonZpVariables2asm(variables)
|
nonZpVariables2asm(variables)
|
||||||
}
|
}
|
||||||
@ -357,7 +357,7 @@ internal class ProgramAndVarsGen(
|
|||||||
|
|
||||||
// normal statically allocated variables
|
// normal statically allocated variables
|
||||||
val variables = varsInSubroutine
|
val variables = varsInSubroutine
|
||||||
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName) }
|
.filter { it.value.type==StNodeType.STATICVAR && !allocator.isZpVar(it.value.scopedName.split('.')) }
|
||||||
.map { it.value as StStaticVariable }
|
.map { it.value as StStaticVariable }
|
||||||
nonZpVariables2asm(variables)
|
nonZpVariables2asm(variables)
|
||||||
|
|
||||||
@ -443,9 +443,10 @@ internal class ProgramAndVarsGen(
|
|||||||
val result = mutableListOf<ZpStringWithInitial>()
|
val result = mutableListOf<ZpStringWithInitial>()
|
||||||
val vars = allocator.zeropageVars.filter { it.value.dt==DataType.STR }
|
val vars = allocator.zeropageVars.filter { it.value.dt==DataType.STR }
|
||||||
for (variable in vars) {
|
for (variable in vars) {
|
||||||
val svar = symboltable.flat.getValue(variable.key) as StStaticVariable
|
val scopedName = variable.key.joinToString(".")
|
||||||
|
val svar = symboltable.flat.getValue(scopedName) as StStaticVariable
|
||||||
if(svar.onetimeInitializationStringValue!=null)
|
if(svar.onetimeInitializationStringValue!=null)
|
||||||
result.add(ZpStringWithInitial(variable.key, variable.value, svar.onetimeInitializationStringValue!!))
|
result.add(ZpStringWithInitial(scopedName, variable.value, svar.onetimeInitializationStringValue!!))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
@ -454,20 +455,21 @@ internal class ProgramAndVarsGen(
|
|||||||
val result = mutableListOf<ZpArrayWithInitial>()
|
val result = mutableListOf<ZpArrayWithInitial>()
|
||||||
val vars = allocator.zeropageVars.filter { it.value.dt in ArrayDatatypes }
|
val vars = allocator.zeropageVars.filter { it.value.dt in ArrayDatatypes }
|
||||||
for (variable in vars) {
|
for (variable in vars) {
|
||||||
val svar = symboltable.flat.getValue(variable.key) as StStaticVariable
|
val scopedName = variable.key.joinToString(".")
|
||||||
|
val svar = symboltable.flat.getValue(scopedName) as StStaticVariable
|
||||||
if(svar.onetimeInitializationArrayValue!=null)
|
if(svar.onetimeInitializationArrayValue!=null)
|
||||||
result.add(ZpArrayWithInitial(variable.key, variable.value, svar.onetimeInitializationArrayValue!!))
|
result.add(ZpArrayWithInitial(scopedName, variable.value, svar.onetimeInitializationArrayValue!!))
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun zeropagevars2asm(varNames: Set<String>) {
|
private fun zeropagevars2asm(varNames: Set<String>) {
|
||||||
val zpVariables = allocator.zeropageVars.filter { it.key in varNames }
|
val namesLists = varNames.map { it.split('.') }.toSet()
|
||||||
|
val zpVariables = allocator.zeropageVars.filter { it.key in namesLists }
|
||||||
for ((scopedName, zpvar) in zpVariables) {
|
for ((scopedName, zpvar) in zpVariables) {
|
||||||
val parts = scopedName.split('.')
|
if (scopedName.size == 2 && scopedName[0] == "cx16" && scopedName[1][0] == 'r' && scopedName[1][1].isDigit())
|
||||||
if (parts.size == 2 && parts[0] == "cx16" && parts[1][0] == 'r' && parts[1][1].isDigit())
|
|
||||||
continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped
|
continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped
|
||||||
asmgen.out("${parts.last()} \t= ${zpvar.address} \t; zp ${zpvar.dt}")
|
asmgen.out("${scopedName.last()} \t= ${zpvar.address} \t; zp ${zpvar.dt}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
|
|
||||||
private val zeropage = options.compTarget.machine.zeropage
|
private val zeropage = options.compTarget.machine.zeropage
|
||||||
internal val globalFloatConsts = mutableMapOf<Double, String>() // all float values in the entire program (value -> varname)
|
internal val globalFloatConsts = mutableMapOf<Double, String>() // all float values in the entire program (value -> varname)
|
||||||
internal val zeropageVars: Map<String, MemoryAllocator.VarAllocation> = zeropage.allocatedVariables
|
internal val zeropageVars: Map<List<String>, MemoryAllocator.VarAllocation> = zeropage.allocatedVariables
|
||||||
|
|
||||||
init {
|
init {
|
||||||
allocateZeropageVariables()
|
allocateZeropageVariables()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun isZpVar(scopedName: String) = scopedName in zeropageVars
|
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropageVars
|
||||||
|
|
||||||
internal fun getFloatAsmConst(number: Double): String {
|
internal fun getFloatAsmConst(number: Double): String {
|
||||||
val asmName = globalFloatConsts[number]
|
val asmName = globalFloatConsts[number]
|
||||||
@ -56,7 +56,7 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
|
|
||||||
varsRequiringZp.forEach { variable ->
|
varsRequiringZp.forEach { variable ->
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName.split('.'),
|
||||||
variable.dt,
|
variable.dt,
|
||||||
variable.length,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
@ -75,7 +75,7 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
if(errors.noErrors()) {
|
if(errors.noErrors()) {
|
||||||
varsPreferringZp.forEach { variable ->
|
varsPreferringZp.forEach { variable ->
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName.split('.'),
|
||||||
variable.dt,
|
variable.dt,
|
||||||
variable.length,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
@ -94,7 +94,7 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName.split('.'),
|
||||||
variable.dt,
|
variable.dt,
|
||||||
variable.length,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
|
@ -325,7 +325,7 @@ internal class AssignmentAsmGen(private val program: Program,
|
|||||||
assignFAC1float(assign.target)
|
assignFAC1float(assign.target)
|
||||||
} else {
|
} else {
|
||||||
// array[x] = -value ... use a tempvar then store that back into the array.
|
// array[x] = -value ... use a tempvar then store that back into the array.
|
||||||
val tempvar = asmgen.getTempVarName(assign.target.datatype).joinToString(".")
|
val tempvar = asmgen.getTempVarName(assign.target.datatype)
|
||||||
val assignToTempvar = AsmAssignment(assign.source,
|
val assignToTempvar = AsmAssignment(assign.source,
|
||||||
AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, assign.target.datatype, assign.target.scope, variableAsmName=tempvar, origAstTarget = assign.target.origAstTarget),
|
AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, assign.target.datatype, assign.target.scope, variableAsmName=tempvar, origAstTarget = assign.target.origAstTarget),
|
||||||
false, program.memsizer, assign.position)
|
false, program.memsizer, assign.position)
|
||||||
|
@ -25,7 +25,7 @@ class TestGoldenRam: FunSpec({
|
|||||||
test("empty golden ram allocations") {
|
test("empty golden ram allocations") {
|
||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests()
|
||||||
val golden = GoldenRam(options, UIntRange.EMPTY)
|
val golden = GoldenRam(options, UIntRange.EMPTY)
|
||||||
val result = golden.allocate("test", DataType.UBYTE, null, null, errors)
|
val result = golden.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
|
||||||
result.expectError { "should not be able to allocate anything" }
|
result.expectError { "should not be able to allocate anything" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,28 +33,28 @@ class TestGoldenRam: FunSpec({
|
|||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests()
|
||||||
val golden = GoldenRam(options, 0x400u until 0x800u)
|
val golden = GoldenRam(options, 0x400u until 0x800u)
|
||||||
|
|
||||||
var result = golden.allocate("test", DataType.UBYTE, null, null, errors)
|
var result = golden.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
|
||||||
var alloc = result.getOrThrow()
|
var alloc = result.getOrThrow()
|
||||||
alloc.size shouldBe 1
|
alloc.size shouldBe 1
|
||||||
alloc.address shouldBe 0x400u
|
alloc.address shouldBe 0x400u
|
||||||
result = golden.allocate("test", DataType.STR, 100, null, errors)
|
result = golden.allocate(listOf("test"), DataType.STR, 100, null, errors)
|
||||||
alloc = result.getOrThrow()
|
alloc = result.getOrThrow()
|
||||||
alloc.size shouldBe 100
|
alloc.size shouldBe 100
|
||||||
alloc.address shouldBe 0x401u
|
alloc.address shouldBe 0x401u
|
||||||
|
|
||||||
repeat(461) {
|
repeat(461) {
|
||||||
result = golden.allocate("test", DataType.UWORD, null, null, errors)
|
result = golden.allocate(listOf("test"), DataType.UWORD, null, null, errors)
|
||||||
alloc = result.getOrThrow()
|
alloc = result.getOrThrow()
|
||||||
alloc.size shouldBe 2
|
alloc.size shouldBe 2
|
||||||
}
|
}
|
||||||
|
|
||||||
result = golden.allocate("test", DataType.UWORD, null, null, errors)
|
result = golden.allocate(listOf("test"), DataType.UWORD, null, null, errors)
|
||||||
result.expectError { "just 1 more byte available" }
|
result.expectError { "just 1 more byte available" }
|
||||||
result = golden.allocate("test", DataType.UBYTE, null, null, errors)
|
result = golden.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
|
||||||
alloc = result.getOrThrow()
|
alloc = result.getOrThrow()
|
||||||
alloc.size shouldBe 1
|
alloc.size shouldBe 1
|
||||||
alloc.address shouldBe golden.region.last
|
alloc.address shouldBe golden.region.last
|
||||||
result = golden.allocate("test", DataType.UBYTE, null, null, errors)
|
result = golden.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
|
||||||
result.expectError { "nothing more available" }
|
result.expectError { "nothing more available" }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -71,26 +71,26 @@ class TestC64Zeropage: FunSpec({
|
|||||||
compTarget = c64target, loadAddress = 999u
|
compTarget = c64target, loadAddress = 999u
|
||||||
))
|
))
|
||||||
|
|
||||||
var result = zp.allocate("", DataType.UBYTE, null, null, errors)
|
var result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
|
||||||
result.onFailure { fail(it.toString()) }
|
result.onFailure { fail(it.toString()) }
|
||||||
result = zp.allocate("", DataType.UBYTE, null, null, errors)
|
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
|
||||||
result.onFailure { fail(it.toString()) }
|
result.onFailure { fail(it.toString()) }
|
||||||
result = zp.allocate("varname", DataType.UBYTE, null, null, errors)
|
result = zp.allocate(listOf("varname"), DataType.UBYTE, null, null, errors)
|
||||||
result.onFailure { fail(it.toString()) }
|
result.onFailure { fail(it.toString()) }
|
||||||
shouldThrow<IllegalArgumentException> { zp.allocate("varname", DataType.UBYTE,null, null, errors) }
|
shouldThrow<IllegalArgumentException> { zp.allocate(listOf("varname"), DataType.UBYTE,null, null, errors) }
|
||||||
result = zp.allocate("varname2", DataType.UBYTE, null, null, errors)
|
result = zp.allocate(listOf("varname2"), DataType.UBYTE, null, null, errors)
|
||||||
result.onFailure { fail(it.toString()) }
|
result.onFailure { fail(it.toString()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testZpFloatEnable") {
|
test("testZpFloatEnable") {
|
||||||
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target, 999u))
|
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target, 999u))
|
||||||
var result = zp.allocate("", DataType.FLOAT, null, null, errors)
|
var result = zp.allocate(emptyList(), DataType.FLOAT, null, null, errors)
|
||||||
result.expectError { "should be allocation error due to disabled floats" }
|
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))
|
val zp2 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, false, c64target, 999u))
|
||||||
result = zp2.allocate("", DataType.FLOAT, null, null, errors)
|
result = zp2.allocate(emptyList(), DataType.FLOAT, null, null, errors)
|
||||||
result.expectError { "should be allocation error due to disabled ZP use" }
|
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))
|
val zp3 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FLOATSAFE, emptyList(), true, false, c64target, 999u))
|
||||||
zp3.allocate("", DataType.FLOAT, null, null, errors)
|
zp3.allocate(emptyList(), DataType.FLOAT, null, null, errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testZpModesWithFloats") {
|
test("testZpModesWithFloats") {
|
||||||
@ -112,7 +112,7 @@ class TestC64Zeropage: FunSpec({
|
|||||||
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, false, c64target, 999u))
|
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, false, c64target, 999u))
|
||||||
println(zp.free)
|
println(zp.free)
|
||||||
zp.availableBytes() shouldBe 0
|
zp.availableBytes() shouldBe 0
|
||||||
val result = zp.allocate("", DataType.BYTE, null, null, errors)
|
val result = zp.allocate(emptyList(), DataType.BYTE, null, null, errors)
|
||||||
result.expectError { "expected error due to disabled ZP use" }
|
result.expectError { "expected error due to disabled ZP use" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,9 +125,9 @@ class TestC64Zeropage: FunSpec({
|
|||||||
zp3.availableBytes() shouldBe 97
|
zp3.availableBytes() shouldBe 97
|
||||||
val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target, 999u))
|
val zp4 = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, c64target, 999u))
|
||||||
zp4.availableBytes() shouldBe 207
|
zp4.availableBytes() shouldBe 207
|
||||||
zp4.allocate("test", DataType.UBYTE, null, null, errors)
|
zp4.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
|
||||||
zp4.availableBytes() shouldBe 206
|
zp4.availableBytes() shouldBe 206
|
||||||
zp4.allocate("test2", DataType.UBYTE, null, null, errors)
|
zp4.allocate(listOf("test2"), DataType.UBYTE, null, null, errors)
|
||||||
zp4.availableBytes() shouldBe 205
|
zp4.availableBytes() shouldBe 205
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,19 +166,19 @@ class TestC64Zeropage: FunSpec({
|
|||||||
zp.hasByteAvailable() shouldBe true
|
zp.hasByteAvailable() shouldBe true
|
||||||
zp.hasWordAvailable() shouldBe true
|
zp.hasWordAvailable() shouldBe true
|
||||||
|
|
||||||
var result = zp.allocate("", DataType.FLOAT, null, null, errors)
|
var result = zp.allocate(emptyList(), DataType.FLOAT, null, null, errors)
|
||||||
result.expectError { "expect allocation error: in regular zp there aren't 5 sequential bytes free" }
|
result.expectError { "expect allocation error: in regular zp there aren't 5 sequential bytes free" }
|
||||||
|
|
||||||
for (i in 0 until zp.availableBytes()) {
|
for (i in 0 until zp.availableBytes()) {
|
||||||
val alloc = zp.allocate("", DataType.UBYTE, null, null, errors)
|
val alloc = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
|
||||||
alloc.getOrElse { throw it }
|
alloc.getOrElse { throw it }
|
||||||
}
|
}
|
||||||
zp.availableBytes() shouldBe 0
|
zp.availableBytes() shouldBe 0
|
||||||
zp.hasByteAvailable() shouldBe false
|
zp.hasByteAvailable() shouldBe false
|
||||||
zp.hasWordAvailable() shouldBe false
|
zp.hasWordAvailable() shouldBe false
|
||||||
result = zp.allocate("", DataType.UBYTE, null, null, errors)
|
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
|
||||||
result.expectError { "expected allocation error" }
|
result.expectError { "expected allocation error" }
|
||||||
result = zp.allocate("", DataType.UWORD, null, null, errors)
|
result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
|
||||||
result.expectError { "expected allocation error" }
|
result.expectError { "expected allocation error" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,47 +187,47 @@ class TestC64Zeropage: FunSpec({
|
|||||||
zp.availableBytes() shouldBe 207
|
zp.availableBytes() shouldBe 207
|
||||||
zp.hasByteAvailable() shouldBe true
|
zp.hasByteAvailable() shouldBe true
|
||||||
zp.hasWordAvailable() shouldBe true
|
zp.hasWordAvailable() shouldBe true
|
||||||
var result = zp.allocate("", DataType.UWORD, null, null, errors)
|
var result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
|
||||||
val loc = result.getOrElse { throw it } .address
|
val loc = result.getOrElse { throw it } .address
|
||||||
loc shouldBeGreaterThan 3u
|
loc shouldBeGreaterThan 3u
|
||||||
loc shouldNotBeIn zp.free
|
loc shouldNotBeIn zp.free
|
||||||
val num = zp.availableBytes() / 2
|
val num = zp.availableBytes() / 2
|
||||||
|
|
||||||
for(i in 0..num-3) {
|
for(i in 0..num-3) {
|
||||||
zp.allocate("", DataType.UWORD, null, null, errors)
|
zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
|
||||||
}
|
}
|
||||||
zp.availableBytes() shouldBe 5
|
zp.availableBytes() shouldBe 5
|
||||||
|
|
||||||
// can't allocate because no more sequential bytes, only fragmented
|
// can't allocate because no more sequential bytes, only fragmented
|
||||||
result = zp.allocate("", DataType.UWORD, null, null, errors)
|
result = zp.allocate(emptyList(), DataType.UWORD, null, null, errors)
|
||||||
result.expectError { "should give allocation error" }
|
result.expectError { "should give allocation error" }
|
||||||
|
|
||||||
for(i in 0..4) {
|
for(i in 0..4) {
|
||||||
zp.allocate("", DataType.UBYTE, null, null, errors)
|
zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
zp.availableBytes() shouldBe 0
|
zp.availableBytes() shouldBe 0
|
||||||
zp.hasByteAvailable() shouldBe false
|
zp.hasByteAvailable() shouldBe false
|
||||||
zp.hasWordAvailable() shouldBe false
|
zp.hasWordAvailable() shouldBe false
|
||||||
result = zp.allocate("", DataType.UBYTE, null, null, errors)
|
result = zp.allocate(emptyList(), DataType.UBYTE, null, null, errors)
|
||||||
result.expectError { "should give allocation error" }
|
result.expectError { "should give allocation error" }
|
||||||
}
|
}
|
||||||
|
|
||||||
test("testEfficientAllocation") {
|
test("testEfficientAllocation") {
|
||||||
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target, 999u))
|
val zp = C64Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.BASICSAFE, emptyList(), true, false, c64target, 999u))
|
||||||
zp.availableBytes() shouldBe 18
|
zp.availableBytes() shouldBe 18
|
||||||
zp.allocate("", DataType.WORD, null, null, errors).getOrElse{throw it}.address shouldBe 0x04u
|
zp.allocate(emptyList(), 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(emptyList(), 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(emptyList(), 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(emptyList(), 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(emptyList(), 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(emptyList(), 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(emptyList(), 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(emptyList(), 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(emptyList(), 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(emptyList(), 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(emptyList(), 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.allocate(emptyList(), DataType.UBYTE, null, null, errors).getOrElse{throw it}.address shouldBe 0xf9u
|
||||||
zp.availableBytes() shouldBe 0
|
zp.availableBytes() shouldBe 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,9 +258,9 @@ class TestCx16Zeropage: FunSpec({
|
|||||||
zp2.availableBytes() shouldBe 175
|
zp2.availableBytes() shouldBe 175
|
||||||
val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target, 999u))
|
val zp3 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target, 999u))
|
||||||
zp3.availableBytes() shouldBe 216
|
zp3.availableBytes() shouldBe 216
|
||||||
zp3.allocate("test", DataType.UBYTE, null, null, errors)
|
zp3.allocate(listOf("test"), DataType.UBYTE, null, null, errors)
|
||||||
zp3.availableBytes() shouldBe 215
|
zp3.availableBytes() shouldBe 215
|
||||||
zp3.allocate("test2", DataType.UBYTE, null, null, errors)
|
zp3.allocate(listOf("test2"), DataType.UBYTE, null, null, errors)
|
||||||
zp3.availableBytes() shouldBe 214
|
zp3.availableBytes() shouldBe 214
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,12 +276,12 @@ class TestCx16Zeropage: FunSpec({
|
|||||||
|
|
||||||
test("preallocated zp vars") {
|
test("preallocated zp vars") {
|
||||||
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target, 999u))
|
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target, 999u))
|
||||||
zp1.allocatedVariables["test"] shouldBe null
|
zp1.allocatedVariables[listOf("test")] shouldBe null
|
||||||
zp1.allocatedVariables["cx16.r0"] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r0")] shouldNotBe null
|
||||||
zp1.allocatedVariables["cx16.r15"] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r15")] shouldNotBe null
|
||||||
zp1.allocatedVariables["cx16.r0L"] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r0L")] shouldNotBe null
|
||||||
zp1.allocatedVariables["cx16.r15L"] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r15L")] shouldNotBe null
|
||||||
zp1.allocatedVariables["cx16.r0sH"] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r0sH")] shouldNotBe null
|
||||||
zp1.allocatedVariables["cx16.r15sH"] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r15sH")] shouldNotBe null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -3,7 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- optimize scoped symbols: .split('.') / .joinToString(".")
|
- optimize array1[index] += / -= array2[index] to not use slow stackeval (attemptAssignOptimizedBinexpr)
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
@ -28,6 +28,7 @@ Compiler:
|
|||||||
- ir: peephole opt: renumber registers in chunks to start with 1 again every time (but keep entry values in mind!)
|
- ir: peephole opt: renumber registers in chunks to start with 1 again every time (but keep entry values in mind!)
|
||||||
- ir: peephole opt: reuse registers in chunks (but keep result registers in mind that pass values out! and don't renumber registers above SyscallRegisterBase!)
|
- ir: peephole opt: reuse registers in chunks (but keep result registers in mind that pass values out! and don't renumber registers above SyscallRegisterBase!)
|
||||||
- ir: add more optimizations in IRPeepholeOptimizer
|
- ir: add more optimizations in IRPeepholeOptimizer
|
||||||
|
- ir: for expressions with array indexes that occur multiple times, can we avoid loading them into new virtualregs everytime and just reuse a single virtualreg as indexer?
|
||||||
- vm: somehow be able to load a label address as value? (VmProgramLoader)
|
- vm: somehow be able to load a label address as value? (VmProgramLoader)
|
||||||
- 6502 codegen: see if we can let for loops skip the loop if startvar>endvar, without adding a lot of code size/duplicating the loop condition.
|
- 6502 codegen: see if we can let for loops skip the loop if startvar>endvar, without adding a lot of code size/duplicating the loop condition.
|
||||||
It is documented behavior to now loop 'around' $00 but it's too easy to forget about!
|
It is documented behavior to now loop 'around' $00 but it's too easy to forget about!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user