diff --git a/compiler/test/vm/TestCompilerVirtual.kt b/compiler/test/vm/TestCompilerVirtual.kt index 4cbaa1cc8..59b33aa11 100644 --- a/compiler/test/vm/TestCompilerVirtual.kt +++ b/compiler/test/vm/TestCompilerVirtual.kt @@ -67,8 +67,12 @@ main { } }""" val target = VMTarget() - val result = compileText(target, true, src, writeAssembly = true)!! - val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir") + var result = compileText(target, false, src, writeAssembly = true)!! + var virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir") + VmRunner().runProgram(virtfile.readText()) + + result = compileText(target, true, src, writeAssembly = true)!! + virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir") VmRunner().runProgram(virtfile.readText()) } @@ -107,7 +111,7 @@ mylabel_inside: }""" val target = VMTarget() - val result = compileText(target, true, src, writeAssembly = true)!! + val result = compileText(target, false, src, writeAssembly = true)!! val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir") VmRunner().runProgram(virtfile.readText()) } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 480161eb6..528afafc4 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -4,6 +4,7 @@ TODO For next release ^^^^^^^^^^^^^^^^ - ir: fix unit tests +- ir: join more codechunks - ir: fix removeWeirdBranches in IR optimizer - update diagram in technical.rst? diff --git a/examples/test.p8 b/examples/test.p8 index 13e8b08d5..4297f2ba4 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,17 +1,20 @@ %import textio -%import floats %zeropage basicsafe main { - float[10] flt - sub start() { - float ff = 9.0 - flt[1] = 42.42 - flt[1] = -9.0 - flt[1] = -ff - flt[1] = -flt[1] ; TODO also fix crash when selecting vm target: fpReg1 out of bounds - floats.print_f(flt[1]) - txt.nl() + cx16.r0 = 42 + goto foobar +my_label: + txt.print_uwhex(cx16.r0, true) + txt.spc() + cx16.r0-- + if cx16.r0 + goto my_label + sys.exit(0) + +foobar: + txt.print("yeooo\n") + goto my_label } } diff --git a/intermediate/src/prog8/intermediate/IRFileReader.kt b/intermediate/src/prog8/intermediate/IRFileReader.kt index 2e1990742..2ab1e7375 100644 --- a/intermediate/src/prog8/intermediate/IRFileReader.kt +++ b/intermediate/src/prog8/intermediate/IRFileReader.kt @@ -464,7 +464,7 @@ class IRFileReader { chunk += it }, ifRight = { - TODO("PROCESS LABEL $it") + throw IRParseException("code chunk should not contain a separate label line anymore, this should be the proper label of a new separate chunk") } ) } diff --git a/intermediate/src/prog8/intermediate/IRInstructions.kt b/intermediate/src/prog8/intermediate/IRInstructions.kt index 8bb7d8d7e..ad68d2dbc 100644 --- a/intermediate/src/prog8/intermediate/IRInstructions.kt +++ b/intermediate/src/prog8/intermediate/IRInstructions.kt @@ -620,7 +620,7 @@ data class IRInstruction( val fpValue: Float?=null, val labelSymbol: String?=null, // symbolic label name as alternative to value (so only for Branch/jump/call Instructions!) val binaryData: Collection?=null, - var branchTarget: IRCodeChunk? = null // will be linked after loading + var branchTarget: IRCodeChunkBase? = null // will be linked after loading ) { // reg1 and fpreg1 can be IN/OUT/INOUT (all others are readonly INPUT) // This knowledge is useful in IL assembly optimizers to see how registers are used. @@ -635,7 +635,7 @@ data class IRInstruction( require(reg2==null || reg2 in 0..65536) {"reg2 out of bounds"} require(fpReg1==null || fpReg1 in 0..65536) {"fpReg1 out of bounds"} require(fpReg2==null || fpReg2 in 0..65536) {"fpReg2 out of bounds"} - if(value!=null) { + if(value!=null && labelSymbol==null) { when (type) { IRDataType.BYTE -> require(value in -128..255) {"value out of range for byte: $value"} IRDataType.WORD -> require(value in -32768..65535) {"value out of range for word: $value"} diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index edadb1dc3..f5f3d1de0 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -76,17 +76,11 @@ class IRProgram(val name: String, val firstBlock = blocks.firstOrNull() if(firstBlock!=null) { if(firstBlock.inlineAssembly.isNotEmpty()) { - TODO("link to inline assembly block") - // irprog.globalInits.next = firstBlock.inlineAssembly.first() + globalInits.next = firstBlock.inlineAssembly.first() } else if(firstBlock.subroutines.isNotEmpty()) { val firstSub = firstBlock.subroutines.first() - if(firstSub.chunks.isNotEmpty()) { - val firstChunk = firstSub.chunks.first() - when(firstChunk) { - is IRCodeChunk -> globalInits.next = firstChunk - else -> TODO("link to other type of chunk") - } - } + if(firstSub.chunks.isNotEmpty()) + globalInits.next = firstSub.chunks.first() } } } @@ -94,7 +88,6 @@ class IRProgram(val name: String, blocks.asSequence().flatMap { it.subroutines }.forEach { sub -> - sub.chunks.withIndex().forEach { (index, chunk) -> fun nextChunk(): IRCodeChunkBase? = if(index?, placeholder operands.clear() } if(operands.isNotEmpty()) { - TODO("placeholder symbol? $operands rest=$rest'") + TODO("huh even more operands? $operands rest=$rest'") // operands.clear() } } diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index 603379c0d..ed1677796 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -132,10 +132,15 @@ class VirtualMachine(irProgram: IRProgram) { } private fun branchTo(i: IRInstruction) { - if(i.branchTarget==null) - TODO("no branchtarget in $i (remove this check)") - pcChunk = i.branchTarget!! - pcIndex = 0 + val target = i.branchTarget + when (target) { + is IRCodeChunk -> { + pcChunk = target + pcIndex = 0 + } + null -> TODO("no branchtarget in $i (remove this check)") + else -> throw IllegalArgumentException("VM can't execute code in a non-codechunk: $target") + } } private fun dispatch(ins: IRInstruction) {