mirror of
https://github.com/irmen/prog8.git
synced 2025-02-22 16:29:05 +00:00
move memoryslab administration from allocator to symboltable
This commit is contained in:
parent
f3960d21a8
commit
fc0a0105b3
@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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?) {
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user