aboutsummaryrefslogtreecommitdiff
path: root/src/comp/middle
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2011-03-28 08:24:11 -0700
committerPatrick Walton <[email protected]>2011-03-28 08:24:58 -0700
commit81695a19f876d6f5d75f18c05b2ae9c40a3221b3 (patch)
treedad8d0fc0026e1d8c99a73c64a5538ccf8db1cd7 /src/comp/middle
parentAdd support for break and cont to rustc (diff)
downloadrust-81695a19f876d6f5d75f18c05b2ae9c40a3221b3.tar.xz
rust-81695a19f876d6f5d75f18c05b2ae9c40a3221b3.zip
rustc: Add support for calling LLVM intrinsics as native functions
Diffstat (limited to 'src/comp/middle')
-rw-r--r--src/comp/middle/metadata.rs1
-rw-r--r--src/comp/middle/trans.rs42
2 files changed, 35 insertions, 8 deletions
diff --git a/src/comp/middle/metadata.rs b/src/comp/middle/metadata.rs
index 9313bcb7..44c62a47 100644
--- a/src/comp/middle/metadata.rs
+++ b/src/comp/middle/metadata.rs
@@ -108,6 +108,7 @@ fn sty_str(ty.sty st, def_str ds) -> str {
alt (abi) {
case (ast.native_abi_rust) {abistr = "r";}
case (ast.native_abi_cdecl) {abistr = "c";}
+ case (ast.native_abi_llvm) {abistr = "l";}
}
ret "N" + abistr + ty_fn_str(args, out, ds);
}
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 9eb20859..8216ab7a 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -5884,18 +5884,44 @@ fn decl_native_fn_and_pair(@crate_ctxt cx,
case (ast.native_abi_cdecl) {
pass_task = false;
}
+ case (ast.native_abi_llvm) {
+ pass_task = false;
+ // We handle this case below.
+ }
}
+
+ auto r;
+ auto rptr;
auto args = ty.ty_fn_args(fn_type);
- 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;
+ 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.RetVoid();
}