devices/runtime: new syscall API

This commit is contained in:
Sebastien Bourdeauducq 2014-08-18 14:33:54 +08:00
parent 65566ec710
commit 15c78df3a2
1 changed files with 29 additions and 19 deletions

View File

@ -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):