vm: allow inline "assembly"

This commit is contained in:
Irmen de Jong 2022-04-30 00:10:07 +02:00
parent 7844ace934
commit 0ee790969d
6 changed files with 40 additions and 9 deletions

View File

@ -1,5 +1,6 @@
package prog8.codegen.virtual
import prog8.code.core.AssemblyError
import prog8.code.core.CompilationOptions
import prog8.code.core.IAssemblyProgram
import prog8.vm.Instruction
@ -46,6 +47,13 @@ internal class AssemblyProgram(override val name: String,
write(line.ins.toString() + "\n")
}
is VmCodeLabel -> write("_" + line.name.joinToString(".") + ":\n")
is VmCodeInlineAsm -> {
val asm = line.assembly.replace("""\{[a-zA-Z\d_\.]+\}""".toRegex()) { matchResult ->
val name = matchResult.value.substring(1, matchResult.value.length-1).split('.')
allocations.get(name).toString() }
write(asm+"\n")
}
else -> throw AssemblyError("invalid vm code line")
}
}
@ -118,4 +126,8 @@ internal class VmCodeChunk(initial: VmCodeLine? = null) {
operator fun plusAssign(chunk: VmCodeChunk) {
lines.addAll(chunk.lines)
}
}
}
internal class VmCodeInlineAsm(asm: String): VmCodeLine() {
val assembly: String = asm.trimIndent()
}

View File

@ -91,6 +91,7 @@ class CodeGen(internal val program: PtProgram,
is PtLabel -> VmCodeChunk(VmCodeLabel(node.scopedName))
is PtBreakpoint -> VmCodeChunk(VmCodeInstruction(Opcode.BREAKPOINT))
is PtConditionalBranch -> translate(node)
is PtInlineAssembly -> VmCodeChunk(VmCodeInlineAsm(node.assembly))
is PtAddressOf,
is PtContainmentCheck,
is PtMemoryByte,
@ -108,7 +109,6 @@ class CodeGen(internal val program: PtProgram,
is PtArray,
is PtString -> throw AssemblyError("should not occur as separate statement node ${node.position}")
is PtAsmSub -> throw AssemblyError("asmsub not supported on virtual machine target ${node.position}")
is PtInlineAssembly -> throw AssemblyError("inline assembly not supported on virtual machine target ${node.position}")
is PtIncludeBinary -> throw AssemblyError("inline binary data not supported on virtual machine target ${node.position}")
else -> TODO("missing codegen for $node")
}

View File

@ -11,7 +11,11 @@ floats {
sub print_f(float value) {
; ---- prints the floating point value (without a newline).
void syscall1fp(sys.SC_PRINTF, value)
%asm {{
loadm.f fr0,{floats.print_f.value}
syscall 35
return
}}
}
sub pow(float value, float power) -> float {
@ -25,8 +29,12 @@ sub fabs(float value) -> float {
}
sub sin(float angle) -> float {
; TODO
return -42.42
; TODO sin.f instruction
%asm {{
loadm.f fr0,{floats.sin.angle}
sin.f fr0,fr0
return
}}
}
sub cos(float angle) -> float {

View File

@ -244,9 +244,18 @@ internal class AstChecker(private val program: Program,
override fun visit(inlineAssembly: InlineAssembly) {
val assembly = inlineAssembly.assembly
if(" rti" in assembly || "\trti" in assembly || " rts" in assembly || "\trts" in assembly ||
" jmp" in assembly || "\tjmp" in assembly || " bra" in assembly || "\tbra" in assembly )
count++
if(compilerOptions.compTarget.name!=VMTarget.NAME) {
if (" rti" in assembly || "\trti" in assembly || " rts" in assembly || "\trts" in assembly ||
" jmp" in assembly || "\tjmp" in assembly || " bra" in assembly || "\tbra" in assembly
)
count++
} else {
if(" return" in assembly || "\treturn" in assembly
|| " jump" in assembly || "\tjump" in assembly
|| " jumpi" in assembly || "\tjumpi" in assembly
)
count++
}
}
}

View File

@ -3,8 +3,9 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- vm: allow inline "asm" where the assembly is vm-code instead of 6502 -- then get rid of the syscall() functions in prog8
- vm: get rid of the syscall() functions in prog8 via inline assembly
- vm: implement missing floating point functions
- vm: get rid of intermediate floats.xxx() functions somehow, instead generate the float instructions directly?
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
- make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment)

View File

@ -9,6 +9,7 @@
main {
sub start() {
txt.print("float tests: ")
floats.print_f(-42.42)
float f1 = 1.2345
float f2 = -9.99
float f3