mirror of
https://github.com/irmen/prog8.git
synced 2024-11-22 15:33:02 +00:00
vm: allow inline "assembly"
This commit is contained in:
parent
7844ace934
commit
0ee790969d
@ -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()
|
||||
}
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user