refactor block options

This commit is contained in:
Irmen de Jong 2023-12-26 22:01:49 +01:00
parent 4bb2b8ca9b
commit 2eb137618e
24 changed files with 98 additions and 66 deletions

View File

@ -71,13 +71,9 @@ class PtProgram(
class PtBlock(name: String,
val address: UInt?,
val library: Boolean,
val forceOutput: Boolean,
val noSymbolPrefixing: Boolean,
val veraFxMuls: Boolean,
val alignment: BlockAlignment,
val source: SourceCode, // taken from the module the block is defined in.
val options: Options,
position: Position
) : PtNamedNode(name, position) {
enum class BlockAlignment {
@ -85,6 +81,12 @@ class PtBlock(name: String,
WORD,
PAGE
}
class Options(val address: UInt? = null,
val forceOutput: Boolean = false,
val noSymbolPrefixing: Boolean = false,
val veraFxMuls: Boolean = false,
val alignment: BlockAlignment = BlockAlignment.NONE)
}

View File

@ -68,8 +68,8 @@ fun printAst(root: PtNode, skipLibraries: Boolean, output: (text: String) -> Uni
}
}
is PtBlock -> {
val addr = if(node.address==null) "" else "@${node.address.toHex()}"
val align = if(node.alignment==PtBlock.BlockAlignment.NONE) "" else "align=${node.alignment}"
val addr = if(node.options.address==null) "" else "@${node.options.address.toHex()}"
val align = if(node.options.alignment==PtBlock.BlockAlignment.NONE) "" else "align=${node.options.alignment}"
"\nblock '${node.name}' $addr $align"
}
is PtConstant -> {

View File

@ -54,7 +54,7 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
}
is PtFunctionCall -> {
val stNode = st.lookup(node.name)!!
if(stNode.astNode.definingBlock()?.noSymbolPrefixing!=true) {
if(stNode.astNode.definingBlock()?.options?.noSymbolPrefixing!=true) {
val index = node.parent.children.indexOf(node)
functionCallsToPrefix += node.parent to index
}
@ -65,14 +65,14 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
lookupName = lookupName.dropLast(4)
}
val stNode = st.lookup(lookupName)!!
if(stNode.astNode.definingBlock()?.noSymbolPrefixing!=true) {
if(stNode.astNode.definingBlock()?.options?.noSymbolPrefixing!=true) {
val index = node.parent.children.indexOf(node)
nodesToPrefix += node.parent to index
}
}
is PtJump -> {
val stNode = st.lookup(node.identifier!!.name) ?: throw AssemblyError("name not found ${node.identifier}")
if(stNode.astNode.definingBlock()?.noSymbolPrefixing!=true) {
if(stNode.astNode.definingBlock()?.options?.noSymbolPrefixing!=true) {
val index = node.parent.children.indexOf(node)
nodesToPrefix += node.parent to index
}
@ -92,7 +92,7 @@ class AsmGen6502(val prefixSymbols: Boolean): ICodeGeneratorBackend {
}
program.allBlocks().forEach { block ->
if (!block.noSymbolPrefixing) {
if (!block.options.noSymbolPrefixing) {
prefixSymbols(block)
}
}
@ -147,7 +147,7 @@ private fun PtVariable.prefix(st: SymbolTable): PtVariable {
is PtIdentifier -> newValue.add(elt.prefix(arrayValue, st))
is PtNumber -> newValue.add(elt)
is PtAddressOf -> {
if(elt.definingBlock()?.noSymbolPrefixing==true)
if(elt.definingBlock()?.options?.noSymbolPrefixing==true)
newValue.add(elt)
else {
val newAddr = PtAddressOf(elt.position)
@ -182,13 +182,13 @@ private fun PtFunctionCall.prefix(parent: PtNode): PtFunctionCall {
private fun PtIdentifier.prefix(parent: PtNode, st: SymbolTable): PtIdentifier {
var target = st.lookup(name)
if(target?.astNode?.definingBlock()?.noSymbolPrefixing==true)
if(target?.astNode?.definingBlock()?.options?.noSymbolPrefixing==true)
return this
if(target==null) {
if(name.endsWith("_lsb") || name.endsWith("_msb")) {
target = st.lookup(name.dropLast(4))
if(target?.astNode?.definingBlock()?.noSymbolPrefixing==true)
if(target?.astNode?.definingBlock()?.options?.noSymbolPrefixing==true)
return this
}
}

View File

@ -255,16 +255,16 @@ internal class ProgramAndVarsGen(
private fun block2asm(block: PtBlock) {
asmgen.out("")
asmgen.out("; ---- block: '${block.name}' ----")
if(block.address!=null)
asmgen.out("* = ${block.address!!.toHex()}")
if(block.options.address!=null)
asmgen.out("* = ${block.options.address!!.toHex()}")
else {
if(block.alignment==PtBlock.BlockAlignment.WORD)
if(block.options.alignment==PtBlock.BlockAlignment.WORD)
asmgen.out("\t.align 2")
else if(block.alignment==PtBlock.BlockAlignment.PAGE)
else if(block.options.alignment==PtBlock.BlockAlignment.PAGE)
asmgen.out("\t.align $100")
}
asmgen.out("${block.name}\t" + (if(block.forceOutput) ".block" else ".proc"))
asmgen.out("${block.name}\t" + (if(block.options.forceOutput) ".block" else ".proc"))
asmgen.outputSourceLine(block)
createBlockVariables(block)
@ -287,7 +287,7 @@ internal class ProgramAndVarsGen(
asmgen.out(" rts\n .bend")
}
asmgen.out(if(block.forceOutput) "\n\t.bend" else "\n\t.pend")
asmgen.out(if(block.options.forceOutput) "\n\t.bend" else "\n\t.pend")
}
private fun getVars(scope: StNode): Map<String, StNode> =
@ -327,7 +327,7 @@ internal class ProgramAndVarsGen(
val asmStartScope: String
val asmEndScope: String
if(sub.definingBlock()!!.forceOutput) {
if(sub.definingBlock()!!.options.forceOutput) {
asmStartScope = ".block"
asmEndScope = ".bend"
} else {
@ -350,7 +350,7 @@ internal class ProgramAndVarsGen(
val asmStartScope: String
val asmEndScope: String
if(sub.definingBlock()!!.forceOutput) {
if(sub.definingBlock()!!.options.forceOutput) {
asmStartScope = ".block"
asmEndScope = ".bend"
} else {

View File

@ -555,7 +555,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
return true
}
in WordDatatypes -> {
if(expr.definingBlock()!!.veraFxMuls) {
if(expr.definingBlock()!!.options.veraFxMuls) {
// cx16 verafx hardware mul
if(expr.right.isSimple()) {
asmgen.assignExpressionToRegister(expr.left, RegisterOrPair.R0, expr.left.type in SignedDatatypes)
@ -598,7 +598,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.out(" jsr math.mul_word_${value}")
}
else {
if(expr.definingBlock()!!.veraFxMuls){
if(expr.definingBlock()!!.options.veraFxMuls){
// cx16 verafx hardware mul
asmgen.assignWordOperandsToAYAndVar(expr.right, expr.left, "cx16.r1")
asmgen.out("""

View File

@ -1440,7 +1440,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
if(value in asmgen.optimizedWordMultiplications) {
asmgen.out(" lda $name | ldy $name+1 | jsr math.mul_word_$value | sta $name | sty $name+1")
} else {
if(block?.veraFxMuls==true)
if(block?.options?.veraFxMuls==true)
// cx16 verafx hardware mul
asmgen.out("""
lda $name
@ -1907,7 +1907,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
sta $name+1""")
}
"*" -> {
if(block?.veraFxMuls==true) {
if(block?.options?.veraFxMuls==true) {
// cx16 verafx hardware muls
if(valueDt==DataType.UBYTE) {
asmgen.out(" lda $otherName | sta cx16.r1")
@ -2075,7 +2075,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
"+" -> asmgen.out(" lda $name | clc | adc $otherName | sta $name | lda $name+1 | adc $otherName+1 | sta $name+1")
"-" -> asmgen.out(" lda $name | sec | sbc $otherName | sta $name | lda $name+1 | sbc $otherName+1 | sta $name+1")
"*" -> {
if(block?.veraFxMuls==true)
if(block?.options?.veraFxMuls==true)
// cx16 verafx hardware muls
asmgen.out("""
lda $name
@ -2279,7 +2279,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
private fun inplacemodificationWordWithValue(name: String, dt: DataType, operator: String, value: PtExpression, block: PtBlock?) {
fun multiplyVarByWordInAY() {
if(block?.veraFxMuls==true)
if(block?.options?.veraFxMuls==true)
// cx16 verafx hardware muls
asmgen.out("""
sta cx16.r1

View File

@ -45,7 +45,7 @@ class TestCodegen: FunSpec({
//}
val codegen = AsmGen6502(prefixSymbols = false)
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main",false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("pi", DataType.UBYTE, ZeropageWish.DONTCARE, PtNumber(DataType.UBYTE, 0.0, Position.DUMMY), null, Position.DUMMY))
sub.add(PtVariable("particleX", DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, 3u, Position.DUMMY))
@ -95,7 +95,7 @@ class TestCodegen: FunSpec({
program.add(block)
// define the "cx16.r0" virtual register
val cx16block = PtBlock("cx16", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val cx16block = PtBlock("cx16", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
cx16block.add(PtMemMapped("r0", DataType.UWORD, 100u, null, Position.DUMMY))
program.add(cx16block)

View File

@ -1661,7 +1661,14 @@ class IRCodeGen(
}
private fun translate(block: PtBlock): IRBlock {
val irBlock = IRBlock(block.name, block.address, block.library, block.forceOutput, translate(block.alignment), block.position) // no use for other attributes yet?
val irBlock = IRBlock(block.name, block.library,
IRBlock.Options(
block.options.address,
block.options.forceOutput,
block.options.noSymbolPrefixing,
block.options.veraFxMuls,
translate(block.options.alignment)
), block.position)
for (child in block.children) {
when(child) {
is PtNop -> { /* nothing */ }

View File

@ -61,6 +61,9 @@ class IRUnusedCodeRemover(
irprog.blocks.forEach { block ->
block.children.filterIsInstance<IRSubroutine>().reversed().forEach { sub ->
if(sub.isEmpty()) {
if(!sub.position.file.startsWith(LIBRARYFILEPREFIX)) {
errors.warn("unused subroutine '${sub.label}'", sub.position)
}
block.children.remove(sub)
irprog.st.removeTree(sub.label)
numRemoved++
@ -80,7 +83,7 @@ class IRUnusedCodeRemover(
block.children.filterIsInstance<IRAsmSubroutine>().reversed().forEach { sub ->
if(sub.isEmpty()) {
if(!sub.position.file.startsWith(LIBRARYFILEPREFIX)) {
errors.warn("unused asmsubroutine ${sub.label}", sub.position)
errors.warn("unused subroutine '${sub.label}'", sub.position)
}
block.children.remove(sub)
irprog.st.removeTree(sub.label)
@ -100,7 +103,7 @@ class IRUnusedCodeRemover(
// check if asmsub is called from another asmsub
irprog.blocks.asSequence().forEach { block ->
block.children.filterIsInstance<IRAsmSubroutine>().forEach { sub ->
if (block.forceOutput || block.library)
if (block.options.forceOutput || block.library)
linkedAsmSubs += sub
if (sub.asmChunk.isNotEmpty()) {
allSubs.forEach { (label, asmsub) ->

View File

@ -8,7 +8,7 @@ import prog8.intermediate.*
class TestIRPeepholeOpt: FunSpec({
fun makeIRProgram(chunks: List<IRCodeChunkBase>): IRProgram {
require(chunks.first().label=="main.start")
val block = IRBlock("main", null, false, false, IRBlock.BlockAlignment.NONE, Position.DUMMY)
val block = IRBlock("main", false, IRBlock.Options(), Position.DUMMY)
val sub = IRSubroutine("main.start", emptyList(), null, Position.DUMMY)
chunks.forEach { sub += it }
block += sub

View File

@ -42,7 +42,7 @@ class TestVmCodeGen: FunSpec({
//}
val codegen = VmCodeGen()
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("pi", DataType.UBYTE, ZeropageWish.DONTCARE, PtNumber(DataType.UBYTE, 0.0, Position.DUMMY), null, Position.DUMMY))
sub.add(PtVariable("particleX", DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, 3u, Position.DUMMY))
@ -92,7 +92,7 @@ class TestVmCodeGen: FunSpec({
program.add(block)
// define the "cx16.r0" virtual register
val cx16block = PtBlock("cx16", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val cx16block = PtBlock("cx16", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
cx16block.add(PtMemMapped("r0", DataType.UWORD, 100u, null, Position.DUMMY))
program.add(cx16block)
@ -121,7 +121,7 @@ class TestVmCodeGen: FunSpec({
//}
val codegen = VmCodeGen()
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY)
@ -184,7 +184,7 @@ class TestVmCodeGen: FunSpec({
//}
val codegen = VmCodeGen()
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY)
@ -243,7 +243,7 @@ class TestVmCodeGen: FunSpec({
//}
val codegen = VmCodeGen()
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY)
@ -290,7 +290,7 @@ class TestVmCodeGen: FunSpec({
//}
val codegen = VmCodeGen()
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("sb1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY)
@ -353,7 +353,7 @@ class TestVmCodeGen: FunSpec({
//}
val codegen = VmCodeGen()
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("sb1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY)
@ -412,7 +412,7 @@ class TestVmCodeGen: FunSpec({
//}
val codegen = VmCodeGen()
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("ub1", DataType.UBYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY)
@ -452,7 +452,7 @@ class TestVmCodeGen: FunSpec({
//}
val codegen = VmCodeGen()
val program = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val block = PtBlock("main", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("test"), Position.DUMMY)
val block = PtBlock("main", false, SourceCode.Generated("test"), PtBlock.Options(), Position.DUMMY)
val romsub = PtAsmSub("routine", 0x5000u, setOf(CpuRegister.Y), emptyList(), emptyList(), false, Position.DUMMY)
block.add(romsub)
val sub = PtSub("start", emptyList(), null, Position.DUMMY)

View File

@ -99,7 +99,7 @@ class UnusedCodeRemover(private val program: Program,
}
return removals
}
if(!subroutine.hasBeenInlined && subroutine.definingModule===program.toplevelModule) {
if(!subroutine.hasBeenInlined && !subroutine.definingModule.isLibrary) {
errors.warn("unused subroutine '${subroutine.name}'", subroutine.position)
}
if(!subroutine.inline) {

View File

@ -187,7 +187,7 @@ class AstPreprocessor(val program: Program,
if(decl.datatype==DataType.ARRAY_W || decl.datatype==DataType.ARRAY_UW) {
if ("splitarrays" in decl.definingBlock.options())
return makeSplitArray(decl)
if("splitarrays" in decl.definingModule.options())
if ("splitarrays" in decl.definingModule.options())
return makeSplitArray(decl)
}

View File

@ -181,7 +181,9 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
}
val (vardecls, statements) = srcBlock.statements.partition { it is VarDecl }
val src = srcBlock.definingModule.source
val block = PtBlock(srcBlock.name, srcBlock.address, srcBlock.isInLibrary, forceOutput, noSymbolPrefixing, veraFxMuls, alignment, src, srcBlock.position)
val block = PtBlock(srcBlock.name, srcBlock.isInLibrary, src,
PtBlock.Options(srcBlock.address, forceOutput, noSymbolPrefixing, veraFxMuls, alignment),
srcBlock.position)
makeScopeVarsDecls(vardecls).forEach { block.add(it) }
for (stmt in statements)
block.add(transformStatement(stmt))

View File

@ -111,7 +111,7 @@ private fun makeSt(): SymbolTable {
// first build the AST
val astProgram = PtProgram("test", DummyMemsizer, DummyStringEncoder)
val astBlock1 = PtBlock("block1", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("block1"), Position.DUMMY)
val astBlock1 = PtBlock("block1", false, SourceCode.Generated("block1"), PtBlock.Options(), Position.DUMMY)
val astConstant1 = PtConstant("c1", DataType.UWORD, 12345.0, Position.DUMMY)
val astConstant2 = PtConstant("blockc", DataType.UWORD, 999.0, Position.DUMMY)
astBlock1.add(astConstant1)
@ -134,7 +134,7 @@ private fun makeSt(): SymbolTable {
astBlock1.add(astSub2)
val astBfunc = PtIdentifier("msb", DataType.UBYTE, Position.DUMMY)
astBlock1.add(astBfunc)
val astBlock2 = PtBlock("block2", null, false, false, false, false, PtBlock.BlockAlignment.NONE, SourceCode.Generated("block2"), Position.DUMMY)
val astBlock2 = PtBlock("block2", false, SourceCode.Generated("block2"), PtBlock.Options(), Position.DUMMY)
val astSub21 = PtSub("sub1", emptyList(), null, Position.DUMMY)
val astSub22 = PtSub("sub2", emptyList(), null, Position.DUMMY)
val astSub221 = PtSub("subsub", emptyList(), null, Position.DUMMY)

View File

@ -394,7 +394,7 @@ main {
start.children.size shouldBe 11
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
vm.memory.getUW(vm.cx16virtualregsBaseAddress) shouldBe 3837u
vm.memory.getUW(0xff02) shouldBe 3837u // $ff02 = cx16.r0
}
}
@ -447,7 +447,7 @@ main {
start.children.size shouldBe 22
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
vm.memory.getUW(vm.cx16virtualregsBaseAddress) shouldBe 3837u
vm.memory.getUW(0xff02) shouldBe 3837u // $ff02 = cx16.r0
}
}

View File

@ -3,8 +3,19 @@
main {
sub start() {
cx16.r0++
str[] names = ["irmen", "de", "jong"]
uword zz = names[1]
txt.print(names[1])
}
sub derp() {
cx16.r0++
}
asmsub hurrah() {
%ir {{
nop
}}
}
}

View File

@ -344,10 +344,14 @@ class IRFileReader {
val attrs = start.attributes.asSequence().associate { it.name.localPart to it.value }
val block = IRBlock(
attrs.getValue("NAME"),
if(attrs.getValue("ADDRESS")=="") null else parseIRValue(attrs.getValue("ADDRESS")).toUInt(),
if(attrs.getValue("LIBRARY")=="") false else attrs.getValue("LIBRARY").toBoolean(),
if(attrs.getValue("FORCEOUTPUT")=="") false else attrs.getValue("FORCEOUTPUT").toBoolean(),
IRBlock.BlockAlignment.valueOf(attrs.getValue("ALIGN")),
IRBlock.Options(
if(attrs.getOrDefault("ADDRESS", "")=="") null else parseIRValue(attrs.getValue("ADDRESS")).toUInt(),
attrs.getOrDefault("FORCEOUTPUT", "false").toBoolean(),
attrs.getOrDefault("NOPREFIXING", "false").toBoolean(),
attrs.getOrDefault("VERAFXMULS", "false").toBoolean(),
IRBlock.BlockAlignment.valueOf(attrs.getValue("ALIGN"))
),
parsePosition(attrs.getValue("POS")))
skipText(reader)
while(reader.peek().isStartElement) {

View File

@ -57,10 +57,12 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
irProgram.blocks.forEach { block ->
xml.writeStartElement("BLOCK")
xml.writeAttribute("NAME", block.label)
xml.writeAttribute("ADDRESS", block.address?.toHex() ?: "")
xml.writeAttribute("ADDRESS", block.options.address?.toHex() ?: "")
xml.writeAttribute("LIBRARY", block.library.toString())
xml.writeAttribute("FORCEOUTPUT", block.forceOutput.toString())
xml.writeAttribute("ALIGN", block.alignment.toString())
xml.writeAttribute("FORCEOUTPUT", block.options.forceOutput.toString())
xml.writeAttribute("NOPREFIXING", block.options.noSymbolPrefixing.toString())
xml.writeAttribute("VERAFXMULS", block.options.veraFxMuls.toString())
xml.writeAttribute("ALIGN", block.options.alignment.toString())
xml.writeAttribute("POS", block.position.toString())
xml.writeCharacters("\n")
block.children.forEach { child ->

View File

@ -345,10 +345,8 @@ class IRProgram(val name: String,
class IRBlock(
val label: String,
val address: UInt?,
val library: Boolean,
val forceOutput: Boolean,
val alignment: BlockAlignment,
val options: Options,
val position: Position
) {
val children = mutableListOf<IIRBlockElement>()
@ -359,6 +357,12 @@ class IRBlock(
PAGE
}
class Options(val address: UInt? = null,
val forceOutput: Boolean = false,
val noSymbolPrefixing: Boolean = false,
val veraFxMuls: Boolean = false,
val alignment: BlockAlignment = BlockAlignment.NONE)
operator fun plusAssign(sub: IRSubroutine) { children += sub }
operator fun plusAssign(sub: IRAsmSubroutine) { children += sub }
operator fun plusAssign(asm: IRInlineAsmChunk) { children += asm }

View File

@ -71,7 +71,7 @@ load.b r1,42
</CODE>
</INITGLOBALS>
<BLOCK NAME="main" ADDRESS="" LIBRARY="false" FORCEOUTPUT="false" ALIGN="NONE" POS="[examples/test.p8: line 2 col 2-5]">
<BLOCK NAME="main" ADDRESS="" LIBRARY="false" FORCEOUTPUT="false" NOPREFIXING="false" VERAFXMULS="false" ALIGN="NONE" POS="[examples/test.p8: line 2 col 2-5]">
<SUB NAME="main.start" RETURNTYPE="" POS="[examples/test.p8: line 4 col 6-8]">
<PARAMS>
</PARAMS>

View File

@ -1,6 +1,5 @@
package prog8.vm
import prog8.code.StMemVar
import prog8.code.core.toHex
import prog8.code.target.virtual.IVirtualMachineRunner
import prog8.intermediate.*
@ -48,12 +47,10 @@ class VirtualMachine(irProgram: IRProgram) {
internal var randomGenerator = Random(0xa55a7653)
internal var randomGeneratorFloats = Random(0xc0d3dbad)
internal var mul16_last_upper = 0u
val cx16virtualregsBaseAddress: Int
init {
program = VmProgramLoader().load(irProgram, memory)
require(irProgram.st.getAsmSymbols().isEmpty()) { "virtual machine can't yet process asmsymbols defined on command line" }
cx16virtualregsBaseAddress = (irProgram.st.lookup("cx16.r0") as? StMemVar)?.address?.toInt() ?: 0xff02
reset(false)
}

View File

@ -38,7 +38,7 @@ class VmProgramLoader {
// load rest of the program into the list
val chunkReplacements = mutableListOf<Pair<IRCodeChunkBase, IRCodeChunk>>()
irProgram.blocks.forEach { block ->
if(block.address!=null)
if(block.options.address!=null)
throw IRParseException("blocks cannot have a load address for vm: ${block.label}")
block.children.forEach { child ->

View File

@ -44,7 +44,7 @@ class TestVm: FunSpec( {
test("vm execution: modify memory") {
val program = IRProgram("test", IRSymbolTable(), getTestOptions(), VMTarget())
val block = IRBlock("testmain", null, false, false, IRBlock.BlockAlignment.NONE, Position.DUMMY)
val block = IRBlock("testmain", false, IRBlock.Options(), Position.DUMMY)
val startSub = IRSubroutine("testmain.testsub", emptyList(), null, Position.DUMMY)
val code = IRCodeChunk(startSub.label, null)
code += IRInstruction(Opcode.NOP)
@ -73,7 +73,7 @@ class TestVm: FunSpec( {
test("asmsub not supported in vm even with IR") {
val program = IRProgram("test", IRSymbolTable(), getTestOptions(), VMTarget())
val block = IRBlock("main", null, false, false, IRBlock.BlockAlignment.NONE, Position.DUMMY)
val block = IRBlock("main", false, IRBlock.Options(), Position.DUMMY)
val startSub = IRAsmSubroutine(
"main.asmstart",
0x2000u,