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") err("subroutines can only be defined in the scope of a block or within another subroutine")
if(subroutine.isAsmSubroutine) { 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) if(subroutine.asmParameterRegisters.size != subroutine.parameters.size)
err("number of asm parameter registers is not the isSameAs as number of parameters") err("number of asm parameter registers is not the isSameAs as number of parameters")
if(subroutine.asmReturnvaluesRegisters.size != subroutine.returntypes.size) if(subroutine.asmReturnvaluesRegisters.size != subroutine.returntypes.size)

View File

@ -14,6 +14,7 @@ import prog8.intermediate.IRFileReader
import prog8.intermediate.IRSubroutine import prog8.intermediate.IRSubroutine
import prog8.intermediate.Opcode import prog8.intermediate.Opcode
import prog8.vm.VmRunner import prog8.vm.VmRunner
import prog8tests.helpers.ErrorReporterForTests
import prog8tests.helpers.compileText import prog8tests.helpers.compileText
import kotlin.io.path.readText import kotlin.io.path.readText
@ -218,7 +219,7 @@ main {
} }
} }
test("asmsub for virtual target") { test("asmsub for virtual target not supported") {
val src = """ val src = """
main { main {
sub start() { sub start() {
@ -230,6 +231,28 @@ main {
lda #99 lda #99
tay tay
rts 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 return
}} }}
} }
@ -237,13 +260,52 @@ main {
val othertarget = Cx16Target() val othertarget = Cx16Target()
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null 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 target = VMTarget()
val result = compileText(target, false, src, writeAssembly = true)!! val result = compileText(target, false, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir") val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val exc = shouldThrow<Exception> { val exc = shouldThrow<Exception> {
VmRunner().runProgram(virtfile.readText()) 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") { test("addresses from labels/subroutines not yet supported in VM") {

View File

@ -38,14 +38,7 @@ class VmProgramLoader {
block.children.forEach { child -> block.children.forEach { child ->
when(child) { when(child) {
is IRAsmSubroutine -> { is IRAsmSubroutine -> throw IRParseException("vm does not support asmsubs (use normal sub): ${child.label}")
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 IRCodeChunk -> programChunks += child is IRCodeChunk -> programChunks += child
is IRInlineAsmChunk -> { is IRInlineAsmChunk -> {
val replacement = addAssemblyToProgram(child, programChunks, variableAddresses) 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.core.spec.style.FunSpec
import io.kotest.matchers.collections.shouldBeEmpty import io.kotest.matchers.collections.shouldBeEmpty
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import prog8.code.core.* import prog8.code.core.*
import prog8.code.target.VMTarget import prog8.code.target.VMTarget
import prog8.intermediate.* 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 program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
val block = IRBlock("main", null, IRBlock.BlockAlignment.NONE, Position.DUMMY) val block = IRBlock("main", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
val startSub = IRAsmSubroutine( val startSub = IRAsmSubroutine(
@ -93,33 +92,16 @@ class TestVm: FunSpec( {
emptySet(), emptySet(),
emptyList(), emptyList(),
emptyList(), emptyList(),
IRInlineAsmChunk("main.asmstart", "inlined asm here", false, null), IRInlineAsmChunk("main.asmstart", "return", false, null),
Position.DUMMY Position.DUMMY
) )
block += startSub block += startSub
program.addBlock(block) 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) 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") { test("vmrunner") {
val runner = VmRunner() val runner = VmRunner()
val irSource="""<?xml version="1.0" encoding="utf-8"?> val irSource="""<?xml version="1.0" encoding="utf-8"?>