rustc: Add support for calling LLVM intrinsics as native functions
This commit is contained in:
parent
6ecdc04788
commit
81695a19f8
5 changed files with 41 additions and 10 deletions
|
@ -346,6 +346,7 @@ type _mod = rec(vec[@view_item] view_items,
|
||||||
tag native_abi {
|
tag native_abi {
|
||||||
native_abi_rust;
|
native_abi_rust;
|
||||||
native_abi_cdecl;
|
native_abi_cdecl;
|
||||||
|
native_abi_llvm;
|
||||||
}
|
}
|
||||||
|
|
||||||
type native_mod = rec(str native_name,
|
type native_mod = rec(str native_name,
|
||||||
|
|
|
@ -162,6 +162,7 @@ impure fn parse_sty(@pstate st, str_def sd) -> ty.sty {
|
||||||
alt (next(st) as char) {
|
alt (next(st) as char) {
|
||||||
case ('r') {abi = ast.native_abi_rust;}
|
case ('r') {abi = ast.native_abi_rust;}
|
||||||
case ('c') {abi = ast.native_abi_cdecl;}
|
case ('c') {abi = ast.native_abi_cdecl;}
|
||||||
|
case ('l') {abi = ast.native_abi_llvm;}
|
||||||
}
|
}
|
||||||
auto func = parse_ty_fn(st, sd);
|
auto func = parse_ty_fn(st, sd);
|
||||||
ret ty.ty_native_fn(abi,func._0,func._1);
|
ret ty.ty_native_fn(abi,func._0,func._1);
|
||||||
|
|
|
@ -1964,6 +1964,8 @@ impure fn parse_item_native_mod(parser p) -> @ast.item {
|
||||||
if (_str.eq(t, "cdecl")) {
|
if (_str.eq(t, "cdecl")) {
|
||||||
} else if (_str.eq(t, "rust")) {
|
} else if (_str.eq(t, "rust")) {
|
||||||
abi = ast.native_abi_rust;
|
abi = ast.native_abi_rust;
|
||||||
|
} else if (_str.eq(t, "llvm")) {
|
||||||
|
abi = ast.native_abi_llvm;
|
||||||
} else {
|
} else {
|
||||||
p.err("unsupported abi: " + t);
|
p.err("unsupported abi: " + t);
|
||||||
fail;
|
fail;
|
||||||
|
|
|
@ -108,6 +108,7 @@ fn sty_str(ty.sty st, def_str ds) -> str {
|
||||||
alt (abi) {
|
alt (abi) {
|
||||||
case (ast.native_abi_rust) {abistr = "r";}
|
case (ast.native_abi_rust) {abistr = "r";}
|
||||||
case (ast.native_abi_cdecl) {abistr = "c";}
|
case (ast.native_abi_cdecl) {abistr = "c";}
|
||||||
|
case (ast.native_abi_llvm) {abistr = "l";}
|
||||||
}
|
}
|
||||||
ret "N" + abistr + ty_fn_str(args, out, ds);
|
ret "N" + abistr + ty_fn_str(args, out, ds);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5884,18 +5884,44 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
|
||||||
case (ast.native_abi_cdecl) {
|
case (ast.native_abi_cdecl) {
|
||||||
pass_task = false;
|
pass_task = false;
|
||||||
}
|
}
|
||||||
}
|
case (ast.native_abi_llvm) {
|
||||||
auto args = ty.ty_fn_args(fn_type);
|
pass_task = false;
|
||||||
for (ty.arg arg in args) {
|
// We handle this case below.
|
||||||
auto llarg = llvm.LLVMGetParam(fcx.llfn, arg_n);
|
}
|
||||||
check (llarg as int != 0);
|
}
|
||||||
call_args += vec(bcx.build.PointerCast(llarg, T_i32()));
|
|
||||||
arg_n += 1u;
|
auto r;
|
||||||
|
auto rptr;
|
||||||
|
auto args = ty.ty_fn_args(fn_type);
|
||||||
|
if (abi == ast.native_abi_llvm) {
|
||||||
|
let vec[ValueRef] call_args = vec();
|
||||||
|
let vec[TypeRef] call_arg_tys = vec();
|
||||||
|
auto i = 0u;
|
||||||
|
while (i < _vec.len[ty.arg](args)) {
|
||||||
|
auto call_arg = llvm.LLVMGetParam(fcx.llfn, i + 3u);
|
||||||
|
call_args += vec(call_arg);
|
||||||
|
call_arg_tys += vec(val_ty(call_arg));
|
||||||
|
i += 1u;
|
||||||
|
}
|
||||||
|
auto llnativefnty = T_fn(call_arg_tys,
|
||||||
|
type_of(cx, ty.ty_fn_ret(fn_type)));
|
||||||
|
auto llnativefn = get_extern_fn(cx.externs, cx.llmod, name,
|
||||||
|
lib.llvm.LLVMCCallConv, llnativefnty);
|
||||||
|
r = bcx.build.Call(llnativefn, call_args);
|
||||||
|
rptr = fcx.llretptr;
|
||||||
|
} else {
|
||||||
|
for (ty.arg arg in args) {
|
||||||
|
auto llarg = llvm.LLVMGetParam(fcx.llfn, arg_n);
|
||||||
|
check (llarg as int != 0);
|
||||||
|
call_args += vec(bcx.build.PointerCast(llarg, T_i32()));
|
||||||
|
arg_n += 1u;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = trans_native(bcx.build, cx.glues, lltaskptr, cx.externs,
|
||||||
|
cx.tn, cx.llmod, name, pass_task, call_args);
|
||||||
|
rptr = bcx.build.BitCast(fcx.llretptr, T_ptr(T_i32()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto r = trans_native(bcx.build, cx.glues, lltaskptr, cx.externs, cx.tn,
|
|
||||||
cx.llmod, name, pass_task, call_args);
|
|
||||||
auto rptr = bcx.build.BitCast(fcx.llretptr, T_ptr(T_i32()));
|
|
||||||
bcx.build.Store(r, rptr);
|
bcx.build.Store(r, rptr);
|
||||||
bcx.build.RetVoid();
|
bcx.build.RetVoid();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue