%asmbinary implemented

This commit is contained in:
Irmen de Jong 2019-04-17 01:33:07 +02:00
parent 0ee43294c4
commit 78fbbf7119
9 changed files with 25 additions and 7 deletions

View File

@ -2169,7 +2169,11 @@ internal class Compiler(private val rootModule: Module,
} }
private fun translateAsmBinary(args: List<DirectiveArg>) { private fun translateAsmBinary(args: List<DirectiveArg>) {
TODO("asmbinary not implemented yet $args") val offset = if(args.size>=2) Value(DataType.UWORD, args[1].int!!) else null
val length = if(args.size==3) Value(DataType.UWORD, args[2].int!!) else null
val filename = args[0].str!!
// reading the actual data is not performed by the compiler but is delegated to the assembler
prog.instr(Opcode.INCLUDE_FILE, offset, length, filename)
} }
} }

View File

@ -23,6 +23,9 @@ open class Instruction(val opcode: Opcode,
else else
"inline_assembly" "inline_assembly"
} }
opcode==Opcode.INCLUDE_FILE -> {
"include_file \"$callLabel\" $arg $arg2"
}
opcode==Opcode.SYSCALL -> { opcode==Opcode.SYSCALL -> {
val syscall = Syscall.values().find { it.callNr==arg!!.numericValue() } val syscall = Syscall.values().find { it.callNr==arg!!.numericValue() }
"syscall $syscall" "syscall $syscall"

View File

@ -262,7 +262,8 @@ enum class Opcode {
BREAKPOINT, // breakpoint BREAKPOINT, // breakpoint
TERMINATE, // end the program TERMINATE, // end the program
LINE, // track source file line number LINE, // track source file line number
INLINE_ASSEMBLY // container to hold inline raw assembly code INLINE_ASSEMBLY, // container to hold inline raw assembly code
INCLUDE_FILE // directive to include a file at this position in the memory of the program
} }
val opcodesWithVarArgument = setOf( val opcodesWithVarArgument = setOf(

View File

@ -472,6 +472,11 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
Opcode.DISCARD_WORD -> " inx" Opcode.DISCARD_WORD -> " inx"
Opcode.DISCARD_FLOAT -> " inx | inx | inx" Opcode.DISCARD_FLOAT -> " inx | inx | inx"
Opcode.INLINE_ASSEMBLY -> "@inline@" + (ins.callLabel2 ?: "") // All of the inline assembly is stored in the calllabel2 property. the '@inline@' is a special marker to process it. Opcode.INLINE_ASSEMBLY -> "@inline@" + (ins.callLabel2 ?: "") // All of the inline assembly is stored in the calllabel2 property. the '@inline@' is a special marker to process it.
Opcode.INCLUDE_FILE -> {
val offset = if(ins.arg==null) "" else ", ${ins.arg.integerValue()}"
val length = if(ins.arg2==null) "" else ", ${ins.arg2.integerValue()}"
" .binary \"${ins.callLabel}\" $offset $length"
}
Opcode.SYSCALL -> { Opcode.SYSCALL -> {
if (ins.arg!!.numericValue() in syscallsForStackVm.map { it.callNr }) if (ins.arg!!.numericValue() in syscallsForStackVm.map { it.callNr })
throw CompilerException("cannot translate vm syscalls to real assembly calls - use *real* subroutine calls instead. Syscall ${ins.arg.numericValue()}") throw CompilerException("cannot translate vm syscalls to real assembly calls - use *real* subroutine calls instead. Syscall ${ins.arg.numericValue()}")

View File

@ -170,6 +170,13 @@ class Program (val name: String,
} }
} }
} }
Opcode.INCLUDE_FILE -> {
val argparts = args!!.split(' ')
val filename = argparts[0]
val offset = if(argparts.size>=2 && argparts[1]!="null") getArgValue(argparts[1], heap) else null
val length = if(argparts.size>=3 && argparts[2]!="null") getArgValue(argparts[2], heap) else null
Instruction(opcode, offset, length, filename)
}
else -> { else -> {
Instruction(opcode, getArgValue(args, heap)) Instruction(opcode, getArgValue(args, heap))
} }

View File

@ -1836,6 +1836,7 @@ class StackVm(private var traceOutputFile: String?) {
Opcode.RSAVEX -> registerSaveX = variables.getValue("X") Opcode.RSAVEX -> registerSaveX = variables.getValue("X")
Opcode.RRESTOREX -> variables["X"] = registerSaveX Opcode.RRESTOREX -> variables["X"] = registerSaveX
Opcode.INLINE_ASSEMBLY -> throw VmExecutionException("stackVm doesn't support executing inline assembly code $ins") Opcode.INLINE_ASSEMBLY -> throw VmExecutionException("stackVm doesn't support executing inline assembly code $ins")
Opcode.INCLUDE_FILE -> throw VmExecutionException("stackVm doesn't support including a file $ins")
Opcode.PUSH_ADDR_HEAPVAR -> { Opcode.PUSH_ADDR_HEAPVAR -> {
val heapId = variables.getValue(ins.callLabel!!).heapId val heapId = variables.getValue(ins.callLabel!!).heapId
if(heapId<0) if(heapId<0)

View File

@ -123,8 +123,7 @@ Directives
This directive can only be used inside a block. This directive can only be used inside a block.
The assembler will include the file as binary bytes at this point, prog8 will not process this at all. The assembler will include the file as binary bytes at this point, prog8 will not process this at all.
The optional offset and length can be used to select a particular piece of the file. The optional offset and length can be used to select a particular piece of the file.
The compiler first looks for the file relative to the same directory as the module containing this statement is in, The file is located relative to the current working directory!
if the file can't be found there it is searched relative to the current directory.
.. data:: %asminclude "<filename>", "scopelabel" .. data:: %asminclude "<filename>", "scopelabel"

View File

@ -74,5 +74,4 @@ of values together (and use it multiple times). Something like::
Misc Misc
^^^^ ^^^^
- implement %asmbinary
- are there any other missing instructions in the code generator? - are there any other missing instructions in the code generator?

View File

@ -4,7 +4,6 @@
sub start() { sub start() {
%asminclude "primes.p8", "derp" %asmbinary "LICENSE", 100, 200
%asmbinary "primes.p8", 10, 20
} }
} }