From 2eb137618e389ab73a424fe99662b87a07d2bb2a Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 26 Dec 2023 22:01:49 +0100 Subject: [PATCH] refactor block options --- codeCore/src/prog8/code/ast/AstBase.kt | 12 +++++++----- codeCore/src/prog8/code/ast/AstPrinter.kt | 4 ++-- .../src/prog8/codegen/cpu6502/AsmGen.kt | 14 +++++++------- .../prog8/codegen/cpu6502/ProgramAndVarsGen.kt | 16 ++++++++-------- .../cpu6502/assignment/AssignmentAsmGen.kt | 4 ++-- .../assignment/AugmentableAssignmentAsmGen.kt | 8 ++++---- codeGenCpu6502/test/TestCodegen.kt | 4 ++-- .../prog8/codegen/intermediate/IRCodeGen.kt | 9 ++++++++- .../intermediate/IRUnusedCodeRemover.kt | 7 +++++-- codeGenIntermediate/test/TestIRPeepholeOpt.kt | 2 +- codeGenIntermediate/test/TestVmCodeGen.kt | 18 +++++++++--------- .../src/prog8/optimizer/UnusedCodeRemover.kt | 2 +- .../compiler/astprocessing/AstPreprocessor.kt | 2 +- .../astprocessing/IntermediateAstMaker.kt | 4 +++- compiler/test/TestSymbolTable.kt | 4 ++-- compiler/test/vm/TestCompilerVirtual.kt | 4 ++-- examples/test.p8 | 11 +++++++++++ .../src/prog8/intermediate/IRFileReader.kt | 10 +++++++--- .../src/prog8/intermediate/IRFileWriter.kt | 8 +++++--- .../src/prog8/intermediate/IRProgram.kt | 10 +++++++--- intermediate/test/TestIRFileInOut.kt | 2 +- virtualmachine/src/prog8/vm/VirtualMachine.kt | 3 --- virtualmachine/src/prog8/vm/VmProgramLoader.kt | 2 +- virtualmachine/test/TestVm.kt | 4 ++-- 24 files changed, 98 insertions(+), 66 deletions(-) diff --git a/codeCore/src/prog8/code/ast/AstBase.kt b/codeCore/src/prog8/code/ast/AstBase.kt index 6b1d890b5..7b5ccb384 100644 --- a/codeCore/src/prog8/code/ast/AstBase.kt +++ b/codeCore/src/prog8/code/ast/AstBase.kt @@ -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) } diff --git a/codeCore/src/prog8/code/ast/AstPrinter.kt b/codeCore/src/prog8/code/ast/AstPrinter.kt index bf3e07184..249721ca4 100644 --- a/codeCore/src/prog8/code/ast/AstPrinter.kt +++ b/codeCore/src/prog8/code/ast/AstPrinter.kt @@ -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 -> { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 0a3785867..222cfdee9 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -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 } } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt index 273515355..109dc0645 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt @@ -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 = @@ -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 { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index e9e974fc3..fb2914cc2 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -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(""" diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index c342ae58b..7f2f94b8a 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -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 diff --git a/codeGenCpu6502/test/TestCodegen.kt b/codeGenCpu6502/test/TestCodegen.kt index de1abd65e..e98c22096 100644 --- a/codeGenCpu6502/test/TestCodegen.kt +++ b/codeGenCpu6502/test/TestCodegen.kt @@ -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) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index 9134dbfe1..e199ff9f2 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -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 */ } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt index 72b525499..055bc0c1c 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt @@ -61,6 +61,9 @@ class IRUnusedCodeRemover( irprog.blocks.forEach { block -> block.children.filterIsInstance().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().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().forEach { sub -> - if (block.forceOutput || block.library) + if (block.options.forceOutput || block.library) linkedAsmSubs += sub if (sub.asmChunk.isNotEmpty()) { allSubs.forEach { (label, asmsub) -> diff --git a/codeGenIntermediate/test/TestIRPeepholeOpt.kt b/codeGenIntermediate/test/TestIRPeepholeOpt.kt index ce01871c2..cb0691840 100644 --- a/codeGenIntermediate/test/TestIRPeepholeOpt.kt +++ b/codeGenIntermediate/test/TestIRPeepholeOpt.kt @@ -8,7 +8,7 @@ import prog8.intermediate.* class TestIRPeepholeOpt: FunSpec({ fun makeIRProgram(chunks: List): 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 diff --git a/codeGenIntermediate/test/TestVmCodeGen.kt b/codeGenIntermediate/test/TestVmCodeGen.kt index e72346f18..cf450cd91 100644 --- a/codeGenIntermediate/test/TestVmCodeGen.kt +++ b/codeGenIntermediate/test/TestVmCodeGen.kt @@ -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) diff --git a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt index 81418df0b..501326efd 100644 --- a/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt +++ b/codeOptimizers/src/prog8/optimizer/UnusedCodeRemover.kt @@ -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) { diff --git a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt index c719738cb..559f659f4 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt @@ -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) } diff --git a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt index 69f0c419d..78d23e813 100644 --- a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt @@ -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)) diff --git a/compiler/test/TestSymbolTable.kt b/compiler/test/TestSymbolTable.kt index 2c2321a6f..ff6fc018b 100644 --- a/compiler/test/TestSymbolTable.kt +++ b/compiler/test/TestSymbolTable.kt @@ -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) diff --git a/compiler/test/vm/TestCompilerVirtual.kt b/compiler/test/vm/TestCompilerVirtual.kt index cbb2458d4..edb76f47c 100644 --- a/compiler/test/vm/TestCompilerVirtual.kt +++ b/compiler/test/vm/TestCompilerVirtual.kt @@ -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 } } diff --git a/examples/test.p8 b/examples/test.p8 index 51782d0da..377f79c4b 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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 + }} + } } diff --git a/intermediate/src/prog8/intermediate/IRFileReader.kt b/intermediate/src/prog8/intermediate/IRFileReader.kt index fbd1f9c6e..1d16c2fab 100644 --- a/intermediate/src/prog8/intermediate/IRFileReader.kt +++ b/intermediate/src/prog8/intermediate/IRFileReader.kt @@ -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) { diff --git a/intermediate/src/prog8/intermediate/IRFileWriter.kt b/intermediate/src/prog8/intermediate/IRFileWriter.kt index 9cd6255e5..15ac7d265 100644 --- a/intermediate/src/prog8/intermediate/IRFileWriter.kt +++ b/intermediate/src/prog8/intermediate/IRFileWriter.kt @@ -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 -> diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index 7e243551a..4ac1bfb40 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -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() @@ -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 } diff --git a/intermediate/test/TestIRFileInOut.kt b/intermediate/test/TestIRFileInOut.kt index 6e678912b..18dd0466a 100644 --- a/intermediate/test/TestIRFileInOut.kt +++ b/intermediate/test/TestIRFileInOut.kt @@ -71,7 +71,7 @@ load.b r1,42 - + diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index 7c838ad75..ad4130338 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -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) } diff --git a/virtualmachine/src/prog8/vm/VmProgramLoader.kt b/virtualmachine/src/prog8/vm/VmProgramLoader.kt index 9317084f2..d9cd40451 100644 --- a/virtualmachine/src/prog8/vm/VmProgramLoader.kt +++ b/virtualmachine/src/prog8/vm/VmProgramLoader.kt @@ -38,7 +38,7 @@ class VmProgramLoader { // load rest of the program into the list val chunkReplacements = mutableListOf>() 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 -> diff --git a/virtualmachine/test/TestVm.kt b/virtualmachine/test/TestVm.kt index eb848c971..924d1b062 100644 --- a/virtualmachine/test/TestVm.kt +++ b/virtualmachine/test/TestVm.kt @@ -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,