Skip to content

Commit

Permalink
slight tweaks to zp and allocator
Browse files Browse the repository at this point in the history
  • Loading branch information
irmen committed Feb 11, 2022
1 parent c8cd6e9 commit 2725c4a
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 26 deletions.
7 changes: 3 additions & 4 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -297,10 +297,9 @@ internal class ProgramAndVarsGen(
}
}

val zp = zeropage
// string and array variables in zeropage that have initializer value, should be initialized
val stringVarsWithInitInZp = zp.variables.filter { it.value.dt==DataType.STR && it.value.initialStringValue!=null }
val arrayVarsWithInitInZp = zp.variables.filter { it.value.dt in ArrayDatatypes && it.value.initialArrayValue!=null }
val stringVarsWithInitInZp = allocator.zeropageVars.filter { it.value.dt==DataType.STR && it.value.initialStringValue!=null }
val arrayVarsWithInitInZp = allocator.zeropageVars.filter { it.value.dt in ArrayDatatypes && it.value.initialArrayValue!=null }
if(stringVarsWithInitInZp.isNotEmpty() || arrayVarsWithInitInZp.isNotEmpty()) {
asmgen.out("; zp str and array initializations")
stringVarsWithInitInZp.forEach {
Expand Down Expand Up @@ -352,7 +351,7 @@ internal class ProgramAndVarsGen(
}

private fun zeropagevars2asm(scope: INameScope) {
val zpVariables = zeropage.variables.filter { it.value.originalScope==scope }
val zpVariables = allocator.zeropageVars.filter { it.value.originalScope==scope }
for ((scopedName, zpvar) in zpVariables) {
if (scopedName.size == 2 && scopedName[0] == "cx16" && scopedName[1][0] == 'r' && scopedName[1][1].isDigit())
continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped
Expand Down
12 changes: 5 additions & 7 deletions codeGenCpu6502/src/prog8/codegen/cpu6502/VariableAllocator.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@ import prog8.ast.base.IntegerDatatypes
import prog8.ast.expressions.StringLiteral
import prog8.ast.statements.Subroutine
import prog8.ast.statements.ZeropageWish
import prog8.compilerinterface.CompilationOptions
import prog8.compilerinterface.IErrorReporter
import prog8.compilerinterface.IVariablesAndConsts
import prog8.compilerinterface.ZeropageType
import prog8.compilerinterface.*


internal class VariableAllocator(private val vars: IVariablesAndConsts,
Expand All @@ -23,6 +20,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
private val memorySlabsInternal = mutableMapOf<String, Pair<UInt, UInt>>()
internal val memorySlabs: Map<String, Pair<UInt, UInt>> = memorySlabsInternal
internal val globalFloatConsts = mutableMapOf<Double, String>() // all float values in the entire program (value -> varname)
internal val zeropageVars: Map<List<String>, Zeropage.ZpAllocation> = zeropage.allocatedVariables

internal fun getMemorySlab(name: String) = memorySlabsInternal[name]
internal fun allocateMemorySlab(name: String, size: UInt, align: UInt) {
Expand Down Expand Up @@ -120,7 +118,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
println(" zeropage free space: ${zeropage.free.size} bytes")
}

internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.variables
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables

private fun numArrayElements(variable: IVariablesAndConsts.StaticVariable) =
when(variable.type) {
Expand All @@ -129,7 +127,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
else -> null
}

fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
internal fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
var extra = subroutineExtras[sub]
return if(extra==null) {
extra = SubroutineExtraAsmInfo()
Expand All @@ -140,7 +138,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
extra
}

fun getFloatAsmConst(number: Double): String {
internal fun getFloatAsmConst(number: Double): String {
val asmName = globalFloatConsts[number]
if(asmName!=null)
return asmName
Expand Down
14 changes: 7 additions & 7 deletions compiler/test/ZeropageTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,12 @@ class TestCx16Zeropage: FunSpec({

test("preallocated zp vars") {
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target))
zp1.variables[listOf("test")] shouldBe null
zp1.variables[listOf("cx16", "r0")] shouldNotBe null
zp1.variables[listOf("cx16", "r15")] shouldNotBe null
zp1.variables[listOf("cx16", "r0L")] shouldNotBe null
zp1.variables[listOf("cx16", "r15L")] shouldNotBe null
zp1.variables[listOf("cx16", "r0sH")] shouldNotBe null
zp1.variables[listOf("cx16", "r15sH")] shouldNotBe null
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
}
})
7 changes: 2 additions & 5 deletions compilerInterfaces/src/prog8/compilerinterface/Zeropage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {

// the variables allocated into Zeropage.
// name (scoped) ==> pair of address to (Datatype + bytesize)
protected val allocatedVariables = mutableMapOf<List<String>, ZpAllocation>()
private val allocations = mutableMapOf<UInt, Pair<List<String>, DataType>>()
val variables: Map<List<String>, ZpAllocation> = allocatedVariables
val allocatedVariables = mutableMapOf<List<String>, ZpAllocation>()

val free = mutableListOf<UInt>() // subclasses must set this to the appropriate free locations.

Expand Down Expand Up @@ -61,7 +59,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
position: Position?,
errors: IErrorReporter): Result<Pair<UInt, Int>, ZeropageAllocationError> {

require(name.isEmpty() || !allocations.values.any { it.first==name } ) {"name can't be allocated twice"}
require(name.isEmpty() || name !in allocatedVariables) {"name can't be allocated twice"}

if(options.zeropage== ZeropageType.DONTUSE)
return Err(ZeropageAllocationError("zero page usage has been disabled"))
Expand Down Expand Up @@ -114,7 +112,6 @@ abstract class Zeropage(protected val options: CompilationOptions) {
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: List<String>, initValue: Expression?, originalScope: INameScope): UInt {
require(size>=0)
free.removeAll(address until address+size.toUInt())
allocations[address] = name to datatype
if(name.isNotEmpty()) {
allocatedVariables[name] = when(datatype) {
in NumericDatatypes -> ZpAllocation(address, datatype, size, originalScope, null, null) // numerical variables in zeropage never have an initial value here because they are set in separate initializer assignments
Expand Down
2 changes: 2 additions & 0 deletions docs/source/todo.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Compiler:
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
- unify FunctioncallExpression + FunctioncallStatement and PipeExpression + Pipe statement classes, may require moving Expression/Statement into interfaces instead of abstract base classes
- for the pipe operator: recognise a placeholder (``?`` or ``%`` or ``_``) in a non-unary function call to allow non-unary functions in the chain; ``4 |> mkword(?, $44) |> print_uw``
OR: change pipe syntax and require function call, but always have implicit first argument added.
- for the pipe operator: make it 100% syntactic sugar so there's no need for asm codegen like translatePipeExpression
- make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment)
but this requires all identifiers in the inlined expression to be changed to fully scoped names.
Expand Down Expand Up @@ -69,5 +70,6 @@ Optimizations:
- translateFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters to a builtin function directly from register(s), this will make the use of a builtin function in a pipe expression more efficient without using a temporary variable
- translateNormalAssignment() -> better code gen for assigning boolean comparison expressions
- when a for loop's loopvariable isn't referenced in the body, and the iterations are known, replace the loop by a repeatloop
but we have no efficient way right now to see if the body references a variable.
- automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements, instead of just a warning.
- introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4
8 changes: 5 additions & 3 deletions examples/test.p8
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

main {
sub start() {
uword zzz = memory("sdfasdf", 100, 0)
str @shared foobar = "zsdfzsdf"
str @shared foobar2 = sc:"zsdfzsdf"
ubyte @shared xx

if xx==1 or xx==2 or xx==3 {
xx++
}
}
}

0 comments on commit 2725c4a

Please sign in to comment.