forked from M-Labs/artiq
devices/runtime: new syscall API
This commit is contained in:
parent
65566ec710
commit
15c78df3a2
|
@ -1,19 +1,21 @@
|
||||||
from llvm import core as lc
|
from llvm import core as lc
|
||||||
from llvm import target as lt
|
from llvm import target as lt
|
||||||
|
|
||||||
|
from artiq.compiler import ir_values
|
||||||
|
|
||||||
lt.initialize_all()
|
lt.initialize_all()
|
||||||
|
|
||||||
_syscalls = [
|
_syscalls = {
|
||||||
("rpc", "i+:i"),
|
"rpc": "i+:i",
|
||||||
("gpio_set", "ii:v"),
|
"gpio_set": "ii:n",
|
||||||
("rtio_set", "iii:v"),
|
"rtio_set": "iii:n",
|
||||||
("rtio_sync", "i:v"),
|
"rtio_sync": "i:n",
|
||||||
("dds_program", "ii:v"),
|
"dds_program": "ii:n",
|
||||||
]
|
}
|
||||||
|
|
||||||
def _str_to_functype(s):
|
def _str_to_functype(s):
|
||||||
_chr_to_type = {
|
_chr_to_type = {
|
||||||
"v": lc.Type.void,
|
"n": lc.Type.void,
|
||||||
"i": lc.Type.int
|
"i": lc.Type.int
|
||||||
}
|
}
|
||||||
assert(s[-2] == ":")
|
assert(s[-2] == ":")
|
||||||
|
@ -31,22 +33,30 @@ def _str_to_functype(s):
|
||||||
|
|
||||||
class LinkInterface:
|
class LinkInterface:
|
||||||
def set_module(self, module):
|
def set_module(self, module):
|
||||||
|
self.module = module
|
||||||
self.var_arg_fixcount = dict()
|
self.var_arg_fixcount = dict()
|
||||||
for func_name, func_type_str in _syscalls:
|
for func_name, func_type_str in _syscalls.items():
|
||||||
var_arg_fixcount, func_type = _str_to_functype(func_type_str)
|
var_arg_fixcount, func_type = _str_to_functype(func_type_str)
|
||||||
if var_arg_fixcount is not None:
|
if var_arg_fixcount is not None:
|
||||||
self.var_arg_fixcount[func_name] = var_arg_fixcount
|
self.var_arg_fixcount[func_name] = var_arg_fixcount
|
||||||
module.add_function(func_type, "__syscall_"+func_name)
|
self.module.add_function(func_type, "__syscall_"+func_name)
|
||||||
|
|
||||||
self.module = module
|
def syscall(self, syscall_name, args, builder):
|
||||||
|
_chr_to_value = {
|
||||||
def emit_syscall(self, builder, syscall_name, args):
|
"n": ir_values.VNone,
|
||||||
if syscall_name in self.var_arg_fixcount:
|
"i": ir_values.VInt
|
||||||
fixcount = self.var_arg_fixcount[syscall_name]
|
}
|
||||||
args = args[:fixcount] \
|
r = _chr_to_value[_syscalls[syscall_name][-1]]()
|
||||||
+ [lc.Constant.int(lc.Type.int(), len(args) - fixcount)] \
|
if builder is not None:
|
||||||
+ args[fixcount:]
|
args = [arg.llvm_value for arg in args]
|
||||||
return builder.call(self.module.get_function_named("__syscall_"+syscall_name), args)
|
if syscall_name in self.var_arg_fixcount:
|
||||||
|
fixcount = self.var_arg_fixcount[syscall_name]
|
||||||
|
args = args[:fixcount] \
|
||||||
|
+ [lc.Constant.int(lc.Type.int(), len(args) - fixcount)] \
|
||||||
|
+ args[fixcount:]
|
||||||
|
llvm_function = self.module.get_function_named("__syscall_"+syscall_name)
|
||||||
|
r.llvm_value = builder.call(llvm_function, args)
|
||||||
|
return r
|
||||||
|
|
||||||
class Environment(LinkInterface):
|
class Environment(LinkInterface):
|
||||||
def __init__(self, ref_period):
|
def __init__(self, ref_period):
|
||||||
|
|
Loading…
Reference in New Issue