vm target can't use asmsub at all, give better error for that

This commit is contained in:
Irmen de Jong 2023-01-26 01:38:13 +01:00
parent f1a7d5ecf7
commit 19a2791c65
4 changed files with 70 additions and 31 deletions

View File

@ -308,6 +308,8 @@ internal class AstChecker(private val program: Program,
err("subroutines can only be defined in the scope of a block or within another subroutine")
if(subroutine.isAsmSubroutine) {
if(compilerOptions.compTarget.name==VMTarget.NAME)
err("cannot use asmsub for vm target, use regular subs")
if(subroutine.asmParameterRegisters.size != subroutine.parameters.size)
err("number of asm parameter registers is not the isSameAs as number of parameters")
if(subroutine.asmReturnvaluesRegisters.size != subroutine.returntypes.size)

View File

@ -14,6 +14,7 @@ import prog8.intermediate.IRFileReader
import prog8.intermediate.IRSubroutine
import prog8.intermediate.Opcode
import prog8.vm.VmRunner
import prog8tests.helpers.ErrorReporterForTests
import prog8tests.helpers.compileText
import kotlin.io.path.readText
@ -218,7 +219,7 @@ main {
}
}
test("asmsub for virtual target") {
test("asmsub for virtual target not supported") {
val src = """
main {
sub start() {
@ -230,6 +231,28 @@ main {
lda #99
tay
rts
}}
}
}"""
val othertarget = Cx16Target()
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
val target = VMTarget()
val errors = ErrorReporterForTests()
compileText(target, false, src, writeAssembly = false, errors = errors) shouldBe null
errors.errors.size shouldBe 1
errors.errors[0] shouldContain "cannot use asmsub for vm target"
}
test("asmsub for virtual target not supported even with IR") {
val src = """
main {
sub start() {
void test(42)
}
asmsub test(ubyte xx @A) -> ubyte @Y {
%ir {{
return
}}
}
@ -237,13 +260,52 @@ main {
val othertarget = Cx16Target()
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
val target = VMTarget()
val errors = ErrorReporterForTests()
compileText(target, false, src, writeAssembly = false, errors = errors) shouldBe null
errors.errors.size shouldBe 1
errors.errors[0] shouldContain "cannot use asmsub for vm target"
}
test("inline asm for virtual target should be IR") {
val src = """
main {
sub start() {
%asm {{
lda #99
tay
rts
}}
}
}"""
val othertarget = Cx16Target()
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
val target = VMTarget()
val result = compileText(target, false, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val exc = shouldThrow<Exception> {
VmRunner().runProgram(virtfile.readText())
}
exc.message shouldContain("does not support non-IR asmsubs")
exc.message shouldContain("does not support real inlined assembly")
}
test("inline asm for virtual target with IR is accepted") {
val src = """
main {
sub start() {
%ir {{
return
}}
}
}"""
val othertarget = Cx16Target()
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
val target = VMTarget()
val result = compileText(target, false, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
VmRunner().runProgram(virtfile.readText())
}
test("addresses from labels/subroutines not yet supported in VM") {

View File

@ -38,14 +38,7 @@ class VmProgramLoader {
block.children.forEach { child ->
when(child) {
is IRAsmSubroutine -> {
if(!child.asmChunk.isIR)
throw IRParseException("vm currently does not support non-IR asmsubs: ${child.label}")
else {
val replacement = addAssemblyToProgram(child.asmChunk, programChunks, variableAddresses)
chunkReplacements += replacement
}
}
is IRAsmSubroutine -> throw IRParseException("vm does not support asmsubs (use normal sub): ${child.label}")
is IRCodeChunk -> programChunks += child
is IRInlineAsmChunk -> {
val replacement = addAssemblyToProgram(child, programChunks, variableAddresses)

View File

@ -2,7 +2,6 @@ import io.kotest.assertions.throwables.shouldThrowWithMessage
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldBeEmpty
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import prog8.code.core.*
import prog8.code.target.VMTarget
import prog8.intermediate.*
@ -84,7 +83,7 @@ class TestVm: FunSpec( {
}
}
test("non-IR asmsub not supported in vm") {
test("asmsub not supported in vm even with IR") {
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
val block = IRBlock("main", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
val startSub = IRAsmSubroutine(
@ -93,33 +92,16 @@ class TestVm: FunSpec( {
emptySet(),
emptyList(),
emptyList(),
IRInlineAsmChunk("main.asmstart", "inlined asm here", false, null),
IRInlineAsmChunk("main.asmstart", "return", false, null),
Position.DUMMY
)
block += startSub
program.addBlock(block)
shouldThrowWithMessage<IRParseException>("vm currently does not support non-IR asmsubs: main.asmstart") {
shouldThrowWithMessage<IRParseException>("vm does not support asmsubs (use normal sub): main.asmstart") {
VirtualMachine(program)
}
}
test("IR asmsub ok in vm") {
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
val block = IRBlock("main", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
val startSub = IRAsmSubroutine(
"main.start",
0x2000u,
emptySet(),
emptyList(),
emptyList(),
IRInlineAsmChunk("main.start", "return", true, null),
Position.DUMMY
)
block += startSub
program.addBlock(block)
VirtualMachine(program).run()
}
test("vmrunner") {
val runner = VmRunner()
val irSource="""<?xml version="1.0" encoding="utf-8"?>