mirror of
https://github.com/irmen/prog8.git
synced 2025-02-25 20:29:04 +00:00
slight tweaks to zp and allocator
This commit is contained in:
parent
c8cd6e9460
commit
2725c4ad4d
@ -297,10 +297,9 @@ internal class ProgramAndVarsGen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val zp = zeropage
|
|
||||||
// string and array variables in zeropage that have initializer value, should be initialized
|
// 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 stringVarsWithInitInZp = allocator.zeropageVars.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 arrayVarsWithInitInZp = allocator.zeropageVars.filter { it.value.dt in ArrayDatatypes && it.value.initialArrayValue!=null }
|
||||||
if(stringVarsWithInitInZp.isNotEmpty() || arrayVarsWithInitInZp.isNotEmpty()) {
|
if(stringVarsWithInitInZp.isNotEmpty() || arrayVarsWithInitInZp.isNotEmpty()) {
|
||||||
asmgen.out("; zp str and array initializations")
|
asmgen.out("; zp str and array initializations")
|
||||||
stringVarsWithInitInZp.forEach {
|
stringVarsWithInitInZp.forEach {
|
||||||
@ -352,7 +351,7 @@ internal class ProgramAndVarsGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun zeropagevars2asm(scope: INameScope) {
|
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) {
|
for ((scopedName, zpvar) in zpVariables) {
|
||||||
if (scopedName.size == 2 && scopedName[0] == "cx16" && scopedName[1][0] == 'r' && scopedName[1][1].isDigit())
|
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
|
continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped
|
||||||
|
@ -8,10 +8,7 @@ import prog8.ast.base.IntegerDatatypes
|
|||||||
import prog8.ast.expressions.StringLiteral
|
import prog8.ast.expressions.StringLiteral
|
||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.ast.statements.ZeropageWish
|
import prog8.ast.statements.ZeropageWish
|
||||||
import prog8.compilerinterface.CompilationOptions
|
import prog8.compilerinterface.*
|
||||||
import prog8.compilerinterface.IErrorReporter
|
|
||||||
import prog8.compilerinterface.IVariablesAndConsts
|
|
||||||
import prog8.compilerinterface.ZeropageType
|
|
||||||
|
|
||||||
|
|
||||||
internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
||||||
@ -23,6 +20,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
private val memorySlabsInternal = mutableMapOf<String, Pair<UInt, UInt>>()
|
private val memorySlabsInternal = mutableMapOf<String, Pair<UInt, UInt>>()
|
||||||
internal val memorySlabs: Map<String, Pair<UInt, UInt>> = memorySlabsInternal
|
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 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 getMemorySlab(name: String) = memorySlabsInternal[name]
|
||||||
internal fun allocateMemorySlab(name: String, size: UInt, align: UInt) {
|
internal fun allocateMemorySlab(name: String, size: UInt, align: UInt) {
|
||||||
@ -120,7 +118,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
println(" zeropage free space: ${zeropage.free.size} bytes")
|
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) =
|
private fun numArrayElements(variable: IVariablesAndConsts.StaticVariable) =
|
||||||
when(variable.type) {
|
when(variable.type) {
|
||||||
@ -129,7 +127,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
|
internal fun subroutineExtra(sub: Subroutine): SubroutineExtraAsmInfo {
|
||||||
var extra = subroutineExtras[sub]
|
var extra = subroutineExtras[sub]
|
||||||
return if(extra==null) {
|
return if(extra==null) {
|
||||||
extra = SubroutineExtraAsmInfo()
|
extra = SubroutineExtraAsmInfo()
|
||||||
@ -140,7 +138,7 @@ internal class VariableAllocator(private val vars: IVariablesAndConsts,
|
|||||||
extra
|
extra
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getFloatAsmConst(number: Double): String {
|
internal fun getFloatAsmConst(number: Double): String {
|
||||||
val asmName = globalFloatConsts[number]
|
val asmName = globalFloatConsts[number]
|
||||||
if(asmName!=null)
|
if(asmName!=null)
|
||||||
return asmName
|
return asmName
|
||||||
|
@ -264,12 +264,12 @@ class TestCx16Zeropage: FunSpec({
|
|||||||
|
|
||||||
test("preallocated zp vars") {
|
test("preallocated zp vars") {
|
||||||
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target))
|
val zp1 = CX16Zeropage(CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, false, cx16target))
|
||||||
zp1.variables[listOf("test")] shouldBe null
|
zp1.allocatedVariables[listOf("test")] shouldBe null
|
||||||
zp1.variables[listOf("cx16", "r0")] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r0")] shouldNotBe null
|
||||||
zp1.variables[listOf("cx16", "r15")] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r15")] shouldNotBe null
|
||||||
zp1.variables[listOf("cx16", "r0L")] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r0L")] shouldNotBe null
|
||||||
zp1.variables[listOf("cx16", "r15L")] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r15L")] shouldNotBe null
|
||||||
zp1.variables[listOf("cx16", "r0sH")] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r0sH")] shouldNotBe null
|
||||||
zp1.variables[listOf("cx16", "r15sH")] shouldNotBe null
|
zp1.allocatedVariables[listOf("cx16", "r15sH")] shouldNotBe null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -29,9 +29,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
|||||||
|
|
||||||
// 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)
|
||||||
protected val allocatedVariables = mutableMapOf<List<String>, ZpAllocation>()
|
val allocatedVariables = mutableMapOf<List<String>, ZpAllocation>()
|
||||||
private val allocations = mutableMapOf<UInt, Pair<List<String>, DataType>>()
|
|
||||||
val variables: Map<List<String>, ZpAllocation> = allocatedVariables
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@ -61,7 +59,7 @@ abstract class Zeropage(protected val options: CompilationOptions) {
|
|||||||
position: Position?,
|
position: Position?,
|
||||||
errors: IErrorReporter): Result<Pair<UInt, Int>, ZeropageAllocationError> {
|
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)
|
if(options.zeropage== ZeropageType.DONTUSE)
|
||||||
return Err(ZeropageAllocationError("zero page usage has been disabled"))
|
return Err(ZeropageAllocationError("zero page usage has been disabled"))
|
||||||
@ -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 {
|
private fun makeAllocation(address: UInt, size: Int, datatype: DataType, name: List<String>, initValue: Expression?, originalScope: INameScope): UInt {
|
||||||
require(size>=0)
|
require(size>=0)
|
||||||
free.removeAll(address until address+size.toUInt())
|
free.removeAll(address until address+size.toUInt())
|
||||||
allocations[address] = name to datatype
|
|
||||||
if(name.isNotEmpty()) {
|
if(name.isNotEmpty()) {
|
||||||
allocatedVariables[name] = when(datatype) {
|
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
|
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
|
||||||
|
@ -27,6 +27,7 @@ Compiler:
|
|||||||
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
|
- 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
|
- 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``
|
- 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
|
- 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)
|
- 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.
|
but this requires all identifiers in the inlined expression to be changed to fully scoped names.
|
||||||
@ -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
|
- 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
|
- 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
|
- 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.
|
- 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
|
- introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4
|
||||||
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
uword zzz = memory("sdfasdf", 100, 0)
|
ubyte @shared xx
|
||||||
str @shared foobar = "zsdfzsdf"
|
|
||||||
str @shared foobar2 = sc:"zsdfzsdf"
|
if xx==1 or xx==2 or xx==3 {
|
||||||
|
xx++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user