forked from M-Labs/artiq
devices/runtime: function type strings + variadic function support
This commit is contained in:
parent
e0ac1193c6
commit
5a3fa5dbff
|
@ -4,20 +4,46 @@ from llvm import target as lt
|
||||||
lt.initialize_all()
|
lt.initialize_all()
|
||||||
|
|
||||||
_syscalls = [
|
_syscalls = [
|
||||||
("print_int", lc.Type.void(), [lc.Type.int()]),
|
("rpc", "i+:i"),
|
||||||
("gpio_set", lc.Type.void(), [lc.Type.int(), lc.Type.int()])
|
("gpio_set", "ii:v")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def _str_to_functype(s):
|
||||||
|
_chr_to_type = {
|
||||||
|
"v": lc.Type.void,
|
||||||
|
"i": lc.Type.int
|
||||||
|
}
|
||||||
|
assert(s[-2] == ":")
|
||||||
|
type_ret = _chr_to_type[s[-1]]()
|
||||||
|
|
||||||
|
var_arg_fixcount = None
|
||||||
|
type_args = []
|
||||||
|
for n, c in enumerate(s[:-2]):
|
||||||
|
if c == "+":
|
||||||
|
type_args.append(lc.Type.int())
|
||||||
|
var_arg_fixcount = n
|
||||||
|
else:
|
||||||
|
type_args.append(_chr_to_type[c]())
|
||||||
|
return var_arg_fixcount, lc.Type.function(type_ret, type_args, var_arg=var_arg_fixcount is not None)
|
||||||
|
|
||||||
class Environment:
|
class Environment:
|
||||||
def set_module(self, module):
|
def set_module(self, module):
|
||||||
for func_name, func_type_ret, func_type_args in _syscalls:
|
self.var_arg_fixcount = dict()
|
||||||
function_type = lc.Type.function(func_type_ret, func_type_args)
|
for func_name, func_type_str in _syscalls:
|
||||||
module.add_function(function_type, "__syscall_"+func_name)
|
var_arg_fixcount, func_type = _str_to_functype(func_type_str)
|
||||||
|
if var_arg_fixcount is not None:
|
||||||
|
self.var_arg_fixcount[func_name] = var_arg_fixcount
|
||||||
|
module.add_function(func_type, "__syscall_"+func_name)
|
||||||
|
|
||||||
self.module = module
|
self.module = module
|
||||||
|
|
||||||
def emit_syscall(self, builder, syscall_name, args):
|
def emit_syscall(self, builder, syscall_name, args):
|
||||||
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:]
|
||||||
|
return builder.call(self.module.get_function_named("__syscall_"+syscall_name), args)
|
||||||
|
|
||||||
def emit_object(self):
|
def emit_object(self):
|
||||||
tm = lt.TargetMachine.new(triple="or1k", cpu="generic")
|
tm = lt.TargetMachine.new(triple="or1k", cpu="generic")
|
||||||
|
|
Loading…
Reference in New Issue