move memoryslab administration from allocator to symboltable

This commit is contained in:
Irmen de Jong 2022-08-21 19:20:56 +02:00
parent f3960d21a8
commit fc0a0105b3
8 changed files with 48 additions and 40 deletions

View File

@ -5,7 +5,7 @@ import prog8.code.core.*
/**
* Tree structure containing all symbol definitions in the program
* (blocks, subroutines, variables (all types) and labels).
* (blocks, subroutines, variables (all types), memoryslabs, and labels).
*/
class SymbolTable : StNode("", StNodeType.GLOBAL, Position.DUMMY) {
fun print() = printIndented(0)
@ -217,10 +217,16 @@ class StMemVar(name: String,
}
}
class StMemorySlab(name: String, val size: UInt, val align: UInt, position: Position):
class StMemorySlab(
name: String,
val size: UInt,
val align: UInt,
val allocatedAddress: UInt? = null, // this is used (for now) in the VM code generator
position: Position
):
StNode(name, StNodeType.MEMORYSLAB, position) {
override fun printProperties() {
print("$name size=$size align=$align")
print("$name size=$size align=$align address=$allocatedAddress")
}
}

View File

@ -8,6 +8,7 @@ import prog8.ast.Program
import prog8.ast.base.FatalAstException
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.code.StMemorySlab
import prog8.code.SymbolTable
import prog8.code.core.*
import prog8.codegen.cpu6502.assignment.*
@ -2896,6 +2897,12 @@ $repeatLabel lda $counterVar
else
extra
}
fun addMemorySlab(name: String, size: UInt, align: UInt, position: Position): String {
val prefixedName = "prog8_memoryslab_$name"
symbolTable.add(StMemorySlab(prefixedName, size, align, null, position))
return prefixedName
}
}

View File

@ -311,12 +311,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
require(name.all { it.isLetterOrDigit() || it=='_' }) {"memory name should be a valid symbol name"}
val size = (fcall.args[1] as NumericLiteral).number.toUInt()
val align = (fcall.args[2] as NumericLiteral).number.toUInt()
val existing = allocations.getMemorySlab(name)
if(existing!=null && (existing.first!=size || existing.second!=align))
throw AssemblyError("memory slab '$name' already exists with a different size or alignment at ${fcall.position}")
val slabname = IdentifierReference(listOf("prog8_slabs", name), fcall.position)
val prefixedName = asmgen.addMemorySlab(name, size, align, fcall.position)
val slabname = IdentifierReference(listOf("prog8_slabs", prefixedName), fcall.position)
slabname.linkParents(fcall)
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UWORD, expression = AddressOf(slabname, fcall.position))
val target =
@ -326,7 +322,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
AsmAssignTarget.fromRegisters(resultRegister ?: RegisterOrPair.AY, false, null, asmgen)
val assign = AsmAssignment(src, target, false, program.memsizer, fcall.position)
asmgen.translateNormalAssignment(assign)
allocations.allocateMemorySlab(name, size, align)
}
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, resultRegister: RegisterOrPair?, scope: Subroutine?) {

View File

@ -170,10 +170,10 @@ internal class ProgramAndVarsGen(
private fun memorySlabs() {
asmgen.out("; memory slabs")
asmgen.out("prog8_slabs\t.block")
for((name, info) in allocator.memorySlabs) {
if(info.second>1u)
asmgen.out("\t.align ${info.second.toHex()}")
asmgen.out("$name\t.fill ${info.first}")
for(slab in symboltable.allMemorySlabs) {
if(slab.align>1u)
asmgen.out("\t.align ${slab.align.toHex()}")
asmgen.out("${slab.name}\t.fill ${slab.size}")
}
asmgen.out("\t.bend")
}

View File

@ -15,8 +15,6 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
) {
private val zeropage = options.compTarget.machine.zeropage
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
@ -24,12 +22,6 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
allocateZeropageVariables()
}
internal fun getMemorySlab(name: String) = memorySlabsInternal[name]
internal fun allocateMemorySlab(name: String, size: UInt, align: UInt) {
memorySlabsInternal[name] = Pair(size, align)
}
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables
internal fun getFloatAsmConst(number: Double): String {

View File

@ -325,17 +325,10 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
val name = (call.args[0] as PtString).value
val size = (call.args[1] as PtNumber).number.toUInt()
val align = (call.args[2] as PtNumber).number.toUInt()
val existing = codeGen.allocations.getMemorySlab(name)
val address = if(existing==null)
codeGen.allocations.allocateMemorySlab(name, size, align)
else if(existing.second!=size || existing.third!=align) {
codeGen.errors.err("memory slab '$name' already exists with a different size or alignment", call.position)
return VmCodeChunk()
}
else
existing.first
val prefixedName = "prog8_memoryslab_$name"
val memorySlab = codeGen.allocations.getMemorySlab(prefixedName) ?: codeGen.allocations.allocateMemorySlab(prefixedName, size, align, call.position)
val code = VmCodeChunk()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, value=address.toInt())
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, value=memorySlab.allocatedAddress!!.toInt())
return code
}

View File

@ -1,5 +1,7 @@
package prog8.codegen.virtual
import prog8.code.StMemorySlab
import prog8.code.StNodeType
import prog8.code.SymbolTable
import prog8.code.ast.PtProgram
import prog8.code.core.*
@ -103,20 +105,24 @@ class VariableAllocator(private val st: SymbolTable, private val program: PtProg
return mm
}
private val memorySlabsInternal = mutableMapOf<String, Triple<UInt, UInt, UInt>>()
internal val memorySlabs: Map<String, Triple<UInt, UInt, UInt>> = memorySlabsInternal
fun allocateMemorySlab(name: String, size: UInt, align: UInt): UInt {
fun allocateMemorySlab(name: String, size: UInt, align: UInt, position: Position): StMemorySlab {
val address =
if(align==0u || align==1u)
freeMemoryStart.toUInt()
else
(freeMemoryStart.toUInt() + align-1u) and (0xffffffffu xor (align-1u))
memorySlabsInternal[name] = Triple(address, size, align)
freeMemoryStart = (address + size).toInt()
return address
val slab = StMemorySlab(name, size, align, address, position)
st.add(slab)
return slab
}
fun getMemorySlab(name: String): Triple<UInt, UInt, UInt>? = memorySlabsInternal[name]
fun getMemorySlab(name: String): StMemorySlab? {
val existing = st.children[name]
return if(existing==null || existing.type!=StNodeType.MEMORYSLAB)
null
else
existing as StMemorySlab
}
}

View File

@ -5,6 +5,15 @@
main {
sub start() {
uword slab1 = memory("slab 1", 2000, 0)
uword slab2 = memory("slab 1", 2000, 0)
uword slab3 = memory("slab other", 2000, 64)
txt.print_uwhex(slab1, true)
txt.print_uwhex(slab2, true)
txt.print_uwhex(slab3, true)
ubyte rasterCount = 231
if rasterCount >= 230