diff options
| author | bors <bors@rust-lang.org> | 2013-07-17 23:52:40 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-07-17 23:52:40 -0700 |
| commit | 30ef79ca6d069e3cc100e3d1332a286cbbc1eab3 (patch) | |
| tree | 181e00e2df0b8430a72e168828f3bd7e34be93f9 | |
| parent | d300a64520294eac39a649c276b0b41a62a0fb99 (diff) | |
| parent | 15ea4a8dd8242a0ee01169872bc538c974e748c9 (diff) | |
| download | rust-30ef79ca6d069e3cc100e3d1332a286cbbc1eab3.tar.gz rust-30ef79ca6d069e3cc100e3d1332a286cbbc1eab3.zip | |
auto merge of #7851 : dotdash/rust/intrinsics, r=pcwalton
| -rw-r--r-- | src/librustc/middle/trans/base.rs | 7 | ||||
| -rw-r--r-- | src/librustc/middle/trans/foreign.rs | 512 |
2 files changed, 169 insertions, 350 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 9d8bac6467e..588b0b5c75f 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1612,6 +1612,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, llfndecl: ValueRef, id: ast::node_id, output_type: ty::t, + skip_retptr: bool, param_substs: Option<@param_substs>, sp: Option<span>) -> fn_ctxt { @@ -1655,7 +1656,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, fcx.llenv = unsafe { llvm::LLVMGetParam(llfndecl, fcx.env_arg_pos() as c_uint) }; - if !ty::type_is_nil(substd_output_type) { + if !ty::type_is_nil(substd_output_type) && !(is_immediate && skip_retptr) { fcx.llretptr = Some(make_return_pointer(fcx, substd_output_type)); } fcx @@ -1667,7 +1668,7 @@ pub fn new_fn_ctxt(ccx: @mut CrateContext, output_type: ty::t, sp: Option<span>) -> fn_ctxt { - new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, None, sp) + new_fn_ctxt_w_id(ccx, path, llfndecl, -1, output_type, false, None, sp) } // NB: must keep 4 fns in sync: @@ -1861,6 +1862,7 @@ pub fn trans_closure(ccx: @mut CrateContext, llfndecl, id, output_type, + false, param_substs, Some(body.span)); let raw_llargs = create_llargs_for_fn_args(fcx, self_arg, decl.inputs); @@ -2079,6 +2081,7 @@ pub fn trans_enum_variant_or_tuple_like_struct<A:IdAndTy>( llfndecl, ctor_id, result_ty, + false, param_substs, None); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index bebed1c3d0d..f7d0e71387b 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -10,7 +10,7 @@ use back::{link, abi}; -use lib::llvm::{ValueRef}; +use lib::llvm::{Pointer, ValueRef}; use lib; use middle::trans::base::*; use middle::trans::cabi; @@ -550,6 +550,66 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, ref_id: Option<ast::node_id>) { debug!("trans_intrinsic(item.ident=%s)", ccx.sess.str_of(item.ident)); + fn simple_llvm_intrinsic(bcx: block, name: &'static str, num_args: uint) { + assert!(num_args <= 4); + let mut args = [0 as ValueRef, ..4]; + let first_real_arg = bcx.fcx.arg_pos(0u); + for uint::range(0, num_args) |i| { + args[i] = get_param(bcx.fcx.llfn, first_real_arg + i); + } + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Ret(bcx, Call(bcx, llfn, args.slice(0, num_args))); + } + + fn memcpy_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { + let ccx = bcx.ccx(); + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = match sizebits { + 32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32), + 64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64), + _ => ccx.sess.fatal("Invalid value for sizebits") + }; + + let decl = bcx.fcx.llfn; + let first_real_arg = bcx.fcx.arg_pos(0u); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); + RetVoid(bcx); + } + + fn memset_intrinsic(bcx: block, name: &'static str, tp_ty: ty::t, sizebits: u8) { + let ccx = bcx.ccx(); + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = match sizebits { + 32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32), + 64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64), + _ => ccx.sess.fatal("Invalid value for sizebits") + }; + + let decl = bcx.fcx.llfn; + let first_real_arg = bcx.fcx.arg_pos(0u); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let val = get_param(decl, first_real_arg + 1); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); + RetVoid(bcx); + } + + fn count_zeros_intrinsic(bcx: block, name: &'static str) { + let x = get_param(bcx.fcx.llfn, bcx.fcx.arg_pos(0u)); + let y = C_i1(false); + let llfn = bcx.ccx().intrinsics.get_copy(&name); + Ret(bcx, Call(bcx, llfn, [x, y])); + } + let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, item.id)); let fcx = new_fn_ctxt_w_id(ccx, @@ -557,16 +617,18 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, decl, item.id, output_type, + true, Some(substs), Some(item.span)); + set_always_inline(fcx.llfn); + // Set the fixed stack segment flag if necessary. if attr::attrs_contains_name(attributes, "fixed_stack_segment") { set_fixed_stack_segment(fcx.llfn); } let mut bcx = top_scope_block(fcx, None); - let lltop = bcx.llbb; let first_real_arg = fcx.arg_pos(0u); let nm = ccx.sess.str_of(item.ident); @@ -595,17 +657,18 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, get_param(decl, first_real_arg + 1u), get_param(decl, first_real_arg + 2u), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } "load" => { let old = AtomicLoad(bcx, get_param(decl, first_real_arg), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } "store" => { AtomicStore(bcx, get_param(decl, first_real_arg + 1u), get_param(decl, first_real_arg), order); + RetVoid(bcx); } op => { // These are all AtomicRMW ops @@ -627,12 +690,10 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg), get_param(decl, first_real_arg + 1u), order); - Store(bcx, old, fcx.llretptr.get()); + Ret(bcx, old); } } - finish_fn(fcx, lltop, bcx); - return; } @@ -640,8 +701,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, "size_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty))); } "move_val" => { // Create a datum reflecting the value being moved. @@ -655,6 +715,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, DROP_EXISTING, get_param(decl, first_real_arg)); + RetVoid(bcx); } "move_val_init" => { // See comments for `"move_val"`. @@ -663,18 +724,17 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let src = Datum {val: get_param(decl, first_real_arg + 1u), ty: tp_ty, mode: mode}; bcx = src.move_to(bcx, INIT, get_param(decl, first_real_arg)); + RetVoid(bcx); } "min_align_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llalign_of_min(ccx, lltp_ty))); } "pref_align_of"=> { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - Store(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_uint(ccx, machine::llalign_of_pref(ccx, lltp_ty))); } "get_tydesc" => { let tp_ty = substs.tys[0]; @@ -687,19 +747,31 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, // the llvm type of intrinsic::TyDesc struct. let userland_tydesc_ty = type_of::type_of(ccx, output_type); let td = PointerCast(bcx, static_ti.tydesc, userland_tydesc_ty); - Store(bcx, td, fcx.llretptr.get()); + Ret(bcx, td); } "init" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); - if !ty::type_is_nil(tp_ty) { - Store(bcx, C_null(lltp_ty), fcx.llretptr.get()); + match bcx.fcx.llretptr { + Some(ptr) => { Store(bcx, C_null(lltp_ty), ptr); RetVoid(bcx); } + None if ty::type_is_nil(tp_ty) => RetVoid(bcx), + None => Ret(bcx, C_null(lltp_ty)), } } "uninit" => { // Do nothing, this is effectively a no-op + let retty = substs.tys[0]; + if ty::type_is_immediate(ccx.tcx, retty) && !ty::type_is_nil(retty) { + unsafe { + Ret(bcx, lib::llvm::llvm::LLVMGetUndef(type_of(ccx, retty).to_ref())); + } + } else { + RetVoid(bcx) + } + } + "forget" => { + RetVoid(bcx); } - "forget" => {} "transmute" => { let (in_type, out_type) = (substs.tys[0], substs.tys[1]); let llintype = type_of::type_of(ccx, in_type); @@ -726,34 +798,45 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, } if !ty::type_is_nil(out_type) { - let lldestptr = fcx.llretptr.get(); let llsrcval = get_param(decl, first_real_arg); if ty::type_is_immediate(ccx.tcx, in_type) { - let lldestptr = PointerCast(bcx, lldestptr, llintype.ptr_to()); - Store(bcx, llsrcval, lldestptr); + match fcx.llretptr { + Some(llretptr) => { + Store(bcx, llsrcval, PointerCast(bcx, llretptr, llintype.ptr_to())); + RetVoid(bcx); + } + None => match (llintype.kind(), llouttype.kind()) { + (Pointer, other) | (other, Pointer) if other != Pointer => { + let tmp = Alloca(bcx, llouttype, ""); + Store(bcx, llsrcval, PointerCast(bcx, tmp, llintype.ptr_to())); + Ret(bcx, Load(bcx, tmp)); + } + _ => Ret(bcx, BitCast(bcx, llsrcval, llouttype)) + } + } } else { // NB: Do not use a Load and Store here. This causes massive // code bloat when `transmute` is used on large structural // types. + let lldestptr = fcx.llretptr.get(); let lldestptr = PointerCast(bcx, lldestptr, Type::i8p()); let llsrcptr = PointerCast(bcx, llsrcval, Type::i8p()); let llsize = llsize_of(ccx, llintype); call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1); + RetVoid(bcx); }; + } else { + RetVoid(bcx); } } "needs_drop" => { let tp_ty = substs.tys[0]; - Store(bcx, - C_bool(ty::type_needs_drop(ccx.tcx, tp_ty)), - fcx.llretptr.get()); + Ret(bcx, C_bool(ty::type_needs_drop(ccx.tcx, tp_ty))); } "contains_managed" => { let tp_ty = substs.tys[0]; - Store(bcx, - C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed()), - fcx.llretptr.get()); + Ret(bcx, C_bool(ty::type_contents(ccx.tcx, tp_ty).contains_managed())); } "visit_tydesc" => { let td = get_param(decl, first_real_arg); @@ -763,6 +846,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let td = PointerCast(bcx, td, ccx.tydesc_type.ptr_to()); glue::call_tydesc_glue_full(bcx, visitor, td, abi::tydesc_field_visit_glue, None); + RetVoid(bcx); } "frame_address" => { let frameaddress = ccx.intrinsics.get_copy(& &"llvm.frameaddress"); @@ -789,6 +873,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, bcx, None, fty, ty::mk_nil(), |bcx| Callee {bcx: bcx, data: Closure(datum)}, ArgVals(arg_vals), Some(Ignore), DontAutorefArg).bcx; + RetVoid(bcx); } "morestack_addr" => { // XXX This is a hack to grab the address of this particular @@ -798,334 +883,65 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let morestack_addr = decl_cdecl_fn( bcx.ccx().llmod, "__morestack", llfty); let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); - Store(bcx, morestack_addr, fcx.llretptr.get()); - } - "memcpy32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memcpy64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memmove32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memmove64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); - } - "memset32" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let val = get_param(decl, first_real_arg + 1); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memset.p0i8.i32"); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); - } - "memset64" => { - let tp_ty = substs.tys[0]; - let lltp_ty = type_of::type_of(ccx, tp_ty); - let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); - let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); - let val = get_param(decl, first_real_arg + 1); - let count = get_param(decl, first_real_arg + 2); - let volatile = C_i1(false); - let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memset.p0i8.i64"); - Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); - } - "sqrtf32" => { - let x = get_param(decl, first_real_arg); - let sqrtf = ccx.intrinsics.get_copy(& &"llvm.sqrt.f32"); - Store(bcx, Call(bcx, sqrtf, [x]), fcx.llretptr.get()); - } - "sqrtf64" => { - let x = get_param(decl, first_real_arg); - let sqrtf = ccx.intrinsics.get_copy(& &"llvm.sqrt.f64"); - Store(bcx, Call(bcx, sqrtf, [x]), fcx.llretptr.get()); - } - "powif32" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powif = ccx.intrinsics.get_copy(& &"llvm.powi.f32"); - Store(bcx, Call(bcx, powif, [a, x]), fcx.llretptr.get()); - } - "powif64" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powif = ccx.intrinsics.get_copy(& &"llvm.powi.f64"); - Store(bcx, Call(bcx, powif, [a, x]), fcx.llretptr.get()); - } - "sinf32" => { - let x = get_param(decl, first_real_arg); - let sinf = ccx.intrinsics.get_copy(& &"llvm.sin.f32"); - Store(bcx, Call(bcx, sinf, [x]), fcx.llretptr.get()); - } - "sinf64" => { - let x = get_param(decl, first_real_arg); - let sinf = ccx.intrinsics.get_copy(& &"llvm.sin.f64"); - Store(bcx, Call(bcx, sinf, [x]), fcx.llretptr.get()); - } - "cosf32" => { - let x = get_param(decl, first_real_arg); - let cosf = ccx.intrinsics.get_copy(& &"llvm.cos.f32"); - Store(bcx, Call(bcx, cosf, [x]), fcx.llretptr.get()); - } - "cosf64" => { - let x = get_param(decl, first_real_arg); - let cosf = ccx.intrinsics.get_copy(& &"llvm.cos.f64"); - Store(bcx, Call(bcx, cosf, [x]), fcx.llretptr.get()); - } - "powf32" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powf = ccx.intrinsics.get_copy(& &"llvm.pow.f32"); - Store(bcx, Call(bcx, powf, [a, x]), fcx.llretptr.get()); - } - "powf64" => { - let a = get_param(decl, first_real_arg); - let x = get_param(decl, first_real_arg + 1u); - let powf = ccx.intrinsics.get_copy(& &"llvm.pow.f64"); - Store(bcx, Call(bcx, powf, [a, x]), fcx.llretptr.get()); - } - "expf32" => { - let x = get_param(decl, first_real_arg); - let expf = ccx.intrinsics.get_copy(& &"llvm.exp.f32"); - Store(bcx, Call(bcx, expf, [x]), fcx.llretptr.get()); - } - "expf64" => { - let x = get_param(decl, first_real_arg); - let expf = ccx.intrinsics.get_copy(& &"llvm.exp.f64"); - Store(bcx, Call(bcx, expf, [x]), fcx.llretptr.get()); - } - "exp2f32" => { - let x = get_param(decl, first_real_arg); - let exp2f = ccx.intrinsics.get_copy(& &"llvm.exp2.f32"); - Store(bcx, Call(bcx, exp2f, [x]), fcx.llretptr.get()); - } - "exp2f64" => { - let x = get_param(decl, first_real_arg); - let exp2f = ccx.intrinsics.get_copy(& &"llvm.exp2.f64"); - Store(bcx, Call(bcx, exp2f, [x]), fcx.llretptr.get()); - } - "logf32" => { - let x = get_param(decl, first_real_arg); - let logf = ccx.intrinsics.get_copy(& &"llvm.log.f32"); - Store(bcx, Call(bcx, logf, [x]), fcx.llretptr.get()); - } - "logf64" => { - let x = get_param(decl, first_real_arg); - let logf = ccx.intrinsics.get_copy(& &"llvm.log.f64"); - Store(bcx, Call(bcx, logf, [x]), fcx.llretptr.get()); - } - "log10f32" => { - let x = get_param(decl, first_real_arg); - let log10f = ccx.intrinsics.get_copy(& &"llvm.log10.f32"); - Store(bcx, Call(bcx, log10f, [x]), fcx.llretptr.get()); - } - "log10f64" => { - let x = get_param(decl, first_real_arg); - let log10f = ccx.intrinsics.get_copy(& &"llvm.log10.f64"); - Store(bcx, Call(bcx, log10f, [x]), fcx.llretptr.get()); - } - "log2f32" => { - let x = get_param(decl, first_real_arg); - let log2f = ccx.intrinsics.get_copy(& &"llvm.log2.f32"); - Store(bcx, Call(bcx, log2f, [x]), fcx.llretptr.get()); - } - "log2f64" => { - let x = get_param(decl, first_real_arg); - let log2f = ccx.intrinsics.get_copy(& &"llvm.log2.f64"); - Store(bcx, Call(bcx, log2f, [x]), fcx.llretptr.get()); - } - "fmaf32" => { - let a = get_param(decl, first_real_arg); - let b = get_param(decl, first_real_arg + 1u); - let c = get_param(decl, first_real_arg + 2u); - let fmaf = ccx.intrinsics.get_copy(& &"llvm.fma.f32"); - Store(bcx, Call(bcx, fmaf, [a, b, c]), fcx.llretptr.get()); - } - "fmaf64" => { - let a = get_param(decl, first_real_arg); - let b = get_param(decl, first_real_arg + 1u); - let c = get_param(decl, first_real_arg + 2u); - let fmaf = ccx.intrinsics.get_copy(& &"llvm.fma.f64"); - Store(bcx, Call(bcx, fmaf, [a, b, c]), fcx.llretptr.get()); - } - "fabsf32" => { - let x = get_param(decl, first_real_arg); - let fabsf = ccx.intrinsics.get_copy(& &"llvm.fabs.f32"); - Store(bcx, Call(bcx, fabsf, [x]), fcx.llretptr.get()); - } - "fabsf64" => { - let x = get_param(decl, first_real_arg); - let fabsf = ccx.intrinsics.get_copy(& &"llvm.fabs.f64"); - Store(bcx, Call(bcx, fabsf, [x]), fcx.llretptr.get()); - } - "floorf32" => { - let x = get_param(decl, first_real_arg); - let floorf = ccx.intrinsics.get_copy(& &"llvm.floor.f32"); - Store(bcx, Call(bcx, floorf, [x]), fcx.llretptr.get()); - } - "floorf64" => { - let x = get_param(decl, first_real_arg); - let floorf = ccx.intrinsics.get_copy(& &"llvm.floor.f64"); - Store(bcx, Call(bcx, floorf, [x]), fcx.llretptr.get()); - } - "ceilf32" => { - let x = get_param(decl, first_real_arg); - let ceilf = ccx.intrinsics.get_copy(& &"llvm.ceil.f32"); - Store(bcx, Call(bcx, ceilf, [x]), fcx.llretptr.get()); - } - "ceilf64" => { - let x = get_param(decl, first_real_arg); - let ceilf = ccx.intrinsics.get_copy(& &"llvm.ceil.f64"); - Store(bcx, Call(bcx, ceilf, [x]), fcx.llretptr.get()); - } - "truncf32" => { - let x = get_param(decl, first_real_arg); - let truncf = ccx.intrinsics.get_copy(& &"llvm.trunc.f32"); - Store(bcx, Call(bcx, truncf, [x]), fcx.llretptr.get()); - } - "truncf64" => { - let x = get_param(decl, first_real_arg); - let truncf = ccx.intrinsics.get_copy(& &"llvm.trunc.f64"); - Store(bcx, Call(bcx, truncf, [x]), fcx.llretptr.get()); - } - "ctpop8" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i8"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop16" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i16"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop32" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i32"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctpop64" => { - let x = get_param(decl, first_real_arg); - let ctpop = ccx.intrinsics.get_copy(& &"llvm.ctpop.i64"); - Store(bcx, Call(bcx, ctpop, [x]), fcx.llretptr.get()) - } - "ctlz8" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i8"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz16" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i16"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz32" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i32"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "ctlz64" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let ctlz = ccx.intrinsics.get_copy(& &"llvm.ctlz.i64"); - Store(bcx, Call(bcx, ctlz, [x, y]), fcx.llretptr.get()) - } - "cttz8" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i8"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz16" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i16"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz32" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i32"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "cttz64" => { - let x = get_param(decl, first_real_arg); - let y = C_i1(false); - let cttz = ccx.intrinsics.get_copy(& &"llvm.cttz.i64"); - Store(bcx, Call(bcx, cttz, [x, y]), fcx.llretptr.get()) - } - "bswap16" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i16"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } - "bswap32" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i32"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } - "bswap64" => { - let x = get_param(decl, first_real_arg); - let cttz = ccx.intrinsics.get_copy(& &"llvm.bswap.i64"); - Store(bcx, Call(bcx, cttz, [x]), fcx.llretptr.get()) - } + Ret(bcx, morestack_addr); + } + "memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32), + "memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64), + "memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32), + "memmove64" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i64", substs.tys[0], 64), + "memset32" => memset_intrinsic(bcx, "llvm.memset.p0i8.i32", substs.tys[0], 32), + "memset64" => memset_intrinsic(bcx, "llvm.memset.p0i8.i64", substs.tys[0], 64), + "sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1), + "sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1), + "powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2), + "powif64" => simple_llvm_intrinsic(bcx, "llvm.powi.f64", 2), + "sinf32" => simple_llvm_intrinsic(bcx, "llvm.sin.f32", 1), + "sinf64" => simple_llvm_intrinsic(bcx, "llvm.sin.f64", 1), + "cosf32" => simple_llvm_intrinsic(bcx, "llvm.cos.f32", 1), + "cosf64" => simple_llvm_intrinsic(bcx, "llvm.cos.f64", 1), + "powf32" => simple_llvm_intrinsic(bcx, "llvm.pow.f32", 2), + "powf64" => simple_llvm_intrinsic(bcx, "llvm.pow.f64", 2), + "expf32" => simple_llvm_intrinsic(bcx, "llvm.exp.f32", 1), + "expf64" => simple_llvm_intrinsic(bcx, "llvm.exp.f64", 1), + "exp2f32" => simple_llvm_intrinsic(bcx, "llvm.exp2.f32", 1), + "exp2f64" => simple_llvm_intrinsic(bcx, "llvm.exp2.f64", 1), + "logf32" => simple_llvm_intrinsic(bcx, "llvm.log.f32", 1), + "logf64" => simple_llvm_intrinsic(bcx, "llvm.log.f64", 1), + "log10f32" => simple_llvm_intrinsic(bcx, "llvm.log10.f32", 1), + "log10f64" => simple_llvm_intrinsic(bcx, "llvm.log10.f64", 1), + "log2f32" => simple_llvm_intrinsic(bcx, "llvm.log2.f32", 1), + "log2f64" => simple_llvm_intrinsic(bcx, "llvm.log2.f64", 1), + "fmaf32" => simple_llvm_intrinsic(bcx, "llvm.fma.f32", 3), + "fmaf64" => simple_llvm_intrinsic(bcx, "llvm.fma.f64", 3), + "fabsf32" => simple_llvm_intrinsic(bcx, "llvm.fabs.f32", 1), + "fabsf64" => simple_llvm_intrinsic(bcx, "llvm.fabs.f64", 1), + "floorf32" => simple_llvm_intrinsic(bcx, "llvm.floor.f32", 1), + "floorf64" => simple_llvm_intrinsic(bcx, "llvm.floor.f64", 1), + "ceilf32" => simple_llvm_intrinsic(bcx, "llvm.ceil.f32", 1), + "ceilf64" => simple_llvm_intrinsic(bcx, "llvm.ceil.f64", 1), + "truncf32" => simple_llvm_intrinsic(bcx, "llvm.trunc.f32", 1), + "truncf64" => simple_llvm_intrinsic(bcx, "llvm.trunc.f64", 1), + "ctpop8" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i8", 1), + "ctpop16" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i16", 1), + "ctpop32" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i32", 1), + "ctpop64" => simple_llvm_intrinsic(bcx, "llvm.ctpop.i64", 1), + "ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"), + "ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"), + "ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"), + "ctlz64" => count_zeros_intrinsic(bcx, "llvm.ctlz.i64"), + "cttz8" => count_zeros_intrinsic(bcx, "llvm.cttz.i8"), + "cttz16" => count_zeros_intrinsic(bcx, "llvm.cttz.i16"), + "cttz32" => count_zeros_intrinsic(bcx, "llvm.cttz.i32"), + "cttz64" => count_zeros_intrinsic(bcx, "llvm.cttz.i64"), + "bswap16" => simple_llvm_intrinsic(bcx, "llvm.bswap.i16", 1), + "bswap32" => simple_llvm_intrinsic(bcx, "llvm.bswap.i32", 1), + "bswap64" => simple_llvm_intrinsic(bcx, "llvm.bswap.i64", 1), _ => { // Could we make this an enum rather than a string? does it get // checked earlier? ccx.sess.span_bug(item.span, "unknown intrinsic"); } } - finish_fn(fcx, lltop, bcx); } /** |
