fixup for memoryslabs

This commit is contained in:
Irmen de Jong 2022-08-21 19:57:52 +02:00
parent 80b630a1e4
commit a182b13e5a
5 changed files with 69 additions and 23 deletions

View File

@ -327,7 +327,7 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
val align = (call.args[2] as PtNumber).number.toUInt()
val label = codeGen.addMemorySlab(name, size, align, call.position)
val code = VmCodeChunk()
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, labelSymbol = label)
code += VmCodeInstruction(Opcode.LOAD, VmDataType.WORD, reg1=resultRegister, labelSymbol = listOf(label))
return code
}

View File

@ -775,15 +775,13 @@ class CodeGen(internal val program: PtProgram,
return code
}
private fun translate(block: PtBlock): VmCodeChunk {
val code = VmCodeChunk()
code += VmCodeComment("BLOCK '${block.name}' addr=${block.address} lib=${block.library}")
private fun translate(block: PtBlock): VmBlock {
val vmblock = VmBlock(block.name, block.address, block.alignment) // no use for other attributes yet?
for (child in block.children) {
if(child !is PtAssignment) // global variable initialization is done elsewhere
code += translateNode(child)
vmblock += translateNode(child)
}
code += VmCodeComment("BLOCK-END '${block.name}'")
return code
return vmblock
}
@ -813,10 +811,10 @@ class CodeGen(internal val program: PtProgram,
internal fun isOne(expression: PtExpression): Boolean = expression is PtNumber && expression.number==1.0
fun addMemorySlab(name: String, size: UInt, align: UInt, position: Position): List<String> {
val scopedName = "prog8_memoryslabs.$name"
symbolTable.add(StMemorySlab(scopedName, size, align, position))
return scopedName.split('.', limit=2)
fun addMemorySlab(name: String, size: UInt, align: UInt, position: Position): String {
val scopedName = "prog8_memoryslab_$name"
symbolTable.add(StMemorySlab(scopedName, size, align, null, position))
return scopedName
}
}

View File

@ -1,6 +1,7 @@
package prog8.codegen.experimental
import prog8.code.SymbolTable
import prog8.code.ast.PtBlock
import prog8.code.core.*
import prog8.vm.Instruction
import prog8.vm.Opcode
@ -20,28 +21,50 @@ class IRProgram(val name: String,
private val st: SymbolTable) {
private val globalInits = mutableListOf<VmCodeLine>()
private val blocks = mutableListOf<VmCodeChunk>()
private val blocks = mutableListOf<VmBlock>()
fun writeFile() {
val outfile = options.outputDir / ("$name.p8ir")
println("Writing intermediate representation to $outfile")
outfile.bufferedWriter().use { out ->
out.write("; PROGRAM '$name'\n")
writeOptions(out)
writeVariableAllocations(out)
out.write("------PROGRAM------\n")
if(!options.dontReinitGlobals) {
out.write("; global var inits\n")
// note: this a block of code that loads values and stores them into the global variables to reset their values.
out.write("\n[INITGLOBALS]\n")
globalInits.forEach { out.writeLine(it) }
out.write("[/INITGLOBALS]\n")
}
out.write("; actual program code\n")
blocks.asSequence().flatMap { it.lines }.forEach { line->out.writeLine(line) }
out.write("\n[CODE]\n")
blocks.forEach { block ->
out.write("\n[BLOCK NAME=${block.name} ADDRESS=${block.address} ALIGN=${block.alignment}]\n")
block.lines.forEach { out.writeLine(it) }
out.write("[/BLOCK]\n")
}
out.write("[/CODE]\n")
}
}
private fun writeOptions(out: BufferedWriter) {
out.write("[OPTIONS]\n")
out.write("compTarget = ${options.compTarget.name}\n")
out.write("output = ${options.output}\n")
out.write("launcher = ${options.launcher}\n")
out.write("zeropage = ${options.zeropage}\n")
out.write("zpReserved = ${options.zpReserved}\n")
out.write("loadAddress = ${options.loadAddress}\n")
out.write("dontReinitGlobals = ${options.dontReinitGlobals}\n")
out.write("evalStackBaseAddress = ${options.evalStackBaseAddress}\n")
// other options not yet useful here?
out.write("[/OPTIONS]\n")
}
private fun writeVariableAllocations(out: Writer) {
out.write("; NORMAL VARIABLES\n")
out.write("\n[VARIABLES]\n")
for (variable in st.allVariables) {
val typeStr = when(variable.dt) {
DataType.UBYTE, DataType.ARRAY_UB, DataType.STR -> "ubyte"
@ -77,8 +100,9 @@ class IRProgram(val name: String,
// TODO have uninitialized variables? (BSS SECTION)
out.write("VAR ${variable.scopedName.joinToString(".")} $typeStr = $value\n")
}
out.write("[/VARIABLES]\n")
out.write("; MEMORY MAPPED VARIABLES\n")
out.write("\n[MEMORYMAPPEDVARIABLES]\n")
for (variable in st.allMemMappedVariables) {
val typeStr = when(variable.dt) {
DataType.UBYTE, DataType.ARRAY_UB, DataType.STR -> "ubyte"
@ -90,9 +114,11 @@ class IRProgram(val name: String,
}
out.write("MAP ${variable.scopedName.joinToString(".")} $typeStr ${variable.address}\n")
}
out.write("[/MEMORYMAPPEDVARIABLES]\n")
out.write("; MEMORY SLABS\n")
st.allMemorySlabs.forEach{ slab -> out.write("MEMORYSLAB _${slab.name} ${slab.size} ${slab.align}\n") }
out.write("\n[MEMORYSLABS]\n")
st.allMemorySlabs.forEach{ slab -> out.write("SLAB _${slab.name} ${slab.size} ${slab.align}\n") }
out.write("[/MEMORYSLABS]\n")
}
private fun BufferedWriter.writeLine(line: VmCodeLine) {
@ -119,8 +145,8 @@ class IRProgram(val name: String,
}
fun addGlobalInits(chunk: VmCodeChunk) = globalInits.addAll(chunk.lines)
fun addBlock(block: VmCodeChunk) = blocks.add(block)
fun getBlocks(): List<VmCodeChunk> = blocks
fun addBlock(block: VmBlock) = blocks.add(block)
fun getBlocks(): List<VmBlock> = blocks
}
sealed class VmCodeLine
@ -167,7 +193,16 @@ class VmCodeInstruction(
class VmCodeLabel(val name: List<String>): VmCodeLine()
internal class VmCodeComment(val comment: String): VmCodeLine()
class VmCodeChunk(initial: VmCodeLine? = null) {
class VmBlock(
val name: String,
val address: UInt?,
val alignment: PtBlock.BlockAlignment,
initial: VmCodeLine? = null
): VmCodeChunk(initial)
open class VmCodeChunk(initial: VmCodeLine? = null) {
val lines = mutableListOf<VmCodeLine>()
init {

View File

@ -49,6 +49,7 @@ class AssemblyProgram(override val name: String, private val allocations: Variab
is VmCodeLabel -> write("_" + line.name.joinToString(".") + ":\n")
is VmCodeInlineAsm -> {
val asm = line.assembly.replace("""\{[a-zA-Z\d_\.]+\}""".toRegex()) { matchResult ->
// "{ X }" -> address of X
val name = matchResult.value.substring(1, matchResult.value.length-1).split('.')
allocations.get(name).toString() }
write(asm+"\n")

View File

@ -1,4 +1,7 @@
main {
uword global1 = 1234
sub start() {
; TODO should generate address
@ -13,5 +16,14 @@ main {
qq=4242 ; TODO should generate symbol not allocated address
c64.EXTCOL = 42 ; TODO wrong VMASM code generated... should generate mapped memory address
qq=global1
qq=other.global2
}
}
other {
uword global2 = 9999
}