diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 40fa44d92ba49..dc6692b45ff51 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -11,7 +11,6 @@ use core::prelude::*; use back::{link, abi}; -use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg}; use lib::llvm::{TypeRef, ValueRef}; use lib; use middle::trans::base::*; @@ -574,118 +573,73 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let mut bcx = top_scope_block(fcx, None); let lltop = bcx.llbb; let first_real_arg = fcx.arg_pos(0u); - match ccx.sess.str_of(item.ident).as_slice() { - "atomic_cxchg" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_cxchg_acq" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_cxchg_rel" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), + + let nm = ccx.sess.str_of(item.ident); + let name = nm.as_slice(); + + // This requires that atomic intrinsics follow a specific naming pattern: + // "atomic_[_], and no ordering means SeqCst + if name.starts_with("atomic_") { + let split : ~[&str] = name.split_iter('_').collect(); + assert!(split.len() >= 2, "Atomic intrinsic not correct format"); + let order = if split.len() == 2 { + lib::llvm::SequentiallyConsistent + } else { + match split[2] { + "relaxed" => lib::llvm::Monotonic, + "acq" => lib::llvm::Acquire, + "rel" => lib::llvm::Release, + "acqrel" => lib::llvm::AcquireRelease, + _ => ccx.sess.fatal("Unknown ordering in atomic intrinsic") + } + }; + + match split[1] { + "cxchg" => { + let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg), + get_param(decl, first_real_arg + 1u), + get_param(decl, first_real_arg + 2u), + order); + Store(bcx, old, fcx.llretptr.get()); + } + "load" => { + let old = AtomicLoad(bcx, get_param(decl, first_real_arg), + order); + Store(bcx, old, fcx.llretptr.get()); + } + "store" => { + AtomicStore(bcx, get_param(decl, first_real_arg + 1u), + get_param(decl, first_real_arg), + order); + } + op => { + // These are all AtomicRMW ops + let atom_op = match op { + "xchg" => lib::llvm::Xchg, + "xadd" => lib::llvm::Add, + "xsub" => lib::llvm::Sub, + "and" => lib::llvm::And, + "nand" => lib::llvm::Nand, + "or" => lib::llvm::Or, + "xor" => lib::llvm::Xor, + "max" => lib::llvm::Max, + "min" => lib::llvm::Min, + "umax" => lib::llvm::UMax, + "umin" => lib::llvm::UMin, + _ => ccx.sess.fatal("Unknown atomic operation") + }; + + let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg), get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_load" => { - let old = AtomicLoad(bcx, - get_param(decl, first_real_arg), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_load_acq" => { - let old = AtomicLoad(bcx, - get_param(decl, first_real_arg), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_store" => { - AtomicStore(bcx, - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg), - SequentiallyConsistent); - } - "atomic_store_rel" => { - AtomicStore(bcx, - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg), - Release); - } - "atomic_xchg" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xchg_acq" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xchg_rel" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd_acq" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd_rel" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub_acq" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub_rel" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); + order); + Store(bcx, old, fcx.llretptr.get()); + } } + + return; + } + + match name { "size_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 8c4ff4415641f..4f532885c92f2 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -117,46 +117,43 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) _, _) => { if abi.is_intrinsic() { - let flags = match cx.ccx.sess.str_of(i.ident).as_slice() { - "size_of" | "pref_align_of" | "min_align_of" | - "uninit" | "init" | "transmute" | "move_val" | - "move_val_init" => use_repr, - - "get_tydesc" | "needs_drop" => use_tydesc, - - "atomic_cxchg" | "atomic_cxchg_acq"| - "atomic_cxchg_rel"| "atomic_load" | - "atomic_load_acq" | "atomic_store" | - "atomic_store_rel"| "atomic_xchg" | - "atomic_xadd" | "atomic_xsub" | - "atomic_xchg_acq" | "atomic_xadd_acq" | - "atomic_xsub_acq" | "atomic_xchg_rel" | - "atomic_xadd_rel" | "atomic_xsub_rel" => 0, - - "visit_tydesc" | "forget" | "frame_address" | - "morestack_addr" => 0, - - "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | - "memset32" | "memset64" => use_repr, - - "sqrtf32" | "sqrtf64" | "powif32" | "powif64" | - "sinf32" | "sinf64" | "cosf32" | "cosf64" | - "powf32" | "powf64" | "expf32" | "expf64" | - "exp2f32" | "exp2f64" | "logf32" | "logf64" | - "log10f32"| "log10f64"| "log2f32" | "log2f64" | - "fmaf32" | "fmaf64" | "fabsf32" | "fabsf64" | - "floorf32"| "floorf64"| "ceilf32" | "ceilf64" | - "truncf32"| "truncf64" => 0, - - "ctpop8" | "ctpop16" | "ctpop32" | "ctpop64" => 0, - - "ctlz8" | "ctlz16" | "ctlz32" | "ctlz64" => 0, - "cttz8" | "cttz16" | "cttz32" | "cttz64" => 0, - - "bswap16" | "bswap32" | "bswap64" => 0, - - // would be cool to make these an enum instead of strings! - _ => fail!("unknown intrinsic in type_use") + let nm = cx.ccx.sess.str_of(i.ident); + let name = nm.as_slice(); + let flags = if name.starts_with("atomic_") { + 0 + } else { + match name { + "size_of" | "pref_align_of" | "min_align_of" | + "uninit" | "init" | "transmute" | "move_val" | + "move_val_init" => use_repr, + + "get_tydesc" | "needs_drop" => use_tydesc, + + "visit_tydesc" | "forget" | "frame_address" | + "morestack_addr" => 0, + + "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | + "memset32" | "memset64" => use_repr, + + "sqrtf32" | "sqrtf64" | "powif32" | "powif64" | + "sinf32" | "sinf64" | "cosf32" | "cosf64" | + "powf32" | "powf64" | "expf32" | "expf64" | + "exp2f32" | "exp2f64" | "logf32" | "logf64" | + "log10f32"| "log10f64"| "log2f32" | "log2f64" | + "fmaf32" | "fmaf64" | "fabsf32" | "fabsf64" | + "floorf32"| "floorf64"| "ceilf32" | "ceilf64" | + "truncf32"| "truncf64" => 0, + + "ctpop8" | "ctpop16" | "ctpop32" | "ctpop64" => 0, + + "ctlz8" | "ctlz16" | "ctlz32" | "ctlz64" => 0, + "cttz8" | "cttz16" | "cttz32" | "cttz64" => 0, + + "bswap16" | "bswap32" | "bswap64" => 0, + + // would be cool to make these an enum instead of strings! + _ => fail!("unknown intrinsic in type_use") + } }; for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;} } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index ea41dff99b896..578b9d9d1f459 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3434,252 +3434,268 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { } let tcx = ccx.tcx; - let str = ccx.tcx.sess.str_of(it.ident); - let (n_tps, inputs, output) = match str.as_slice() { - "size_of" | - "pref_align_of" | "min_align_of" => (1u, ~[], ty::mk_uint()), - "init" => (1u, ~[], param(ccx, 0u)), - "uninit" => (1u, ~[], param(ccx, 0u)), - "forget" => (1u, ~[ param(ccx, 0) ], ty::mk_nil()), - "transmute" => (2, ~[ param(ccx, 0) ], param(ccx, 1)), - "move_val" | "move_val_init" => { - (1u, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), param(ccx, 0)), - param(ccx, 0u) - ], - ty::mk_nil()) - } - "needs_drop" => (1u, ~[], ty::mk_bool()), - - "atomic_cxchg" | "atomic_cxchg_acq"| "atomic_cxchg_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, - ty::re_bound(ty::br_anon(0)), - ty::mk_int()), - ty::mk_int(), - ty::mk_int() - ], - ty::mk_int()) - } - "atomic_load" | "atomic_load_acq" => { - (0, - ~[ - ty::mk_imm_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()) - ], - ty::mk_int()) - } - "atomic_store" | "atomic_store_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), - ty::mk_int() - ], - ty::mk_nil()) - } - "atomic_xchg" | "atomic_xadd" | "atomic_xsub" | - "atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" | - "atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), - ty::mk_int() - ], - ty::mk_int()) - } - - "get_tydesc" => { - // FIXME (#3730): return *intrinsic::tydesc, not *() - (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) - } - "visit_tydesc" => { - let tydesc_name = special_idents::tydesc; - assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); - let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); - let (_, visitor_object_ty) = ty::visitor_object_ty(tcx); - let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { - ty: tydesc_ty, - mutbl: ast::m_imm - }); - (0, ~[ td_ptr, visitor_object_ty ], ty::mk_nil()) - } - "frame_address" => { - let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy { - purity: ast::impure_fn, - sigil: ast::BorrowedSigil, - onceness: ast::Once, - region: ty::re_bound(ty::br_anon(0)), - bounds: ty::EmptyBuiltinBounds(), - sig: ty::FnSig { - bound_lifetime_names: opt_vec::Empty, - inputs: ~[ty::mk_imm_ptr(ccx.tcx, ty::mk_mach_uint(ast::ty_u8))], - output: ty::mk_nil() - } - }); - (0u, ~[fty], ty::mk_nil()) - } - "morestack_addr" => { - (0u, ~[], ty::mk_nil_ptr(ccx.tcx)) - } - "memcpy32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memcpy64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u64() - ], - ty::mk_nil()) - } - "memmove32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memmove64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), + let nm = ccx.tcx.sess.str_of(it.ident); + let name = nm.as_slice(); + let (n_tps, inputs, output) = if name.starts_with("atomic_") { + let split : ~[&str] = name.split_iter('_').collect(); + assert!(split.len() >= 2, "Atomic intrinsic not correct format"); + + //We only care about the operation here + match split[1] { + "cxchg" => (0, ~[ty::mk_mut_rptr(tcx, + ty::re_bound(ty::br_anon(0)), + ty::mk_int()), + ty::mk_int(), + ty::mk_int() + ], ty::mk_int()), + "load" => (0, + ~[ + ty::mk_imm_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()) + ], + ty::mk_int()), + "store" => (0, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), + ty::mk_int() + ], + ty::mk_nil()), + + "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | + "min" | "umax" | "umin" => { + (0, ~[ty::mk_mut_rptr(tcx, + ty::re_bound(ty::br_anon(0)), + ty::mk_int()), ty::mk_int() ], ty::mk_int()) + } + + op => { + tcx.sess.span_err(it.span, + fmt!("unrecognized atomic operation function: `%s`", + op)); + return; + } + } + + } else { + match name { + "size_of" | + "pref_align_of" | "min_align_of" => (1u, ~[], ty::mk_uint()), + "init" => (1u, ~[], param(ccx, 0u)), + "uninit" => (1u, ~[], param(ccx, 0u)), + "forget" => (1u, ~[ param(ccx, 0) ], ty::mk_nil()), + "transmute" => (2, ~[ param(ccx, 0) ], param(ccx, 1)), + "move_val" | "move_val_init" => { + (1u, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), param(ccx, 0)), + param(ccx, 0u) + ], + ty::mk_nil()) + } + "needs_drop" => (1u, ~[], ty::mk_bool()), + + "atomic_xchg" | "atomic_xadd" | "atomic_xsub" | + "atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" | + "atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => { + (0, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), + ty::mk_int() + ], + ty::mk_int()) + } + + "get_tydesc" => { + // FIXME (#3730): return *intrinsic::tydesc, not *() + (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) + } + "visit_tydesc" => { + let tydesc_name = special_idents::tydesc; + assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); + let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + let (_, visitor_object_ty) = ty::visitor_object_ty(tcx); + let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { + ty: tydesc_ty, mutbl: ast::m_imm - }), - ty::mk_u64() - ], - ty::mk_nil()) - } - "memset32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_u8(), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memset64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_u8(), - ty::mk_u64() - ], - ty::mk_nil()) - } - "sqrtf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "sqrtf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "powif32" => { - (0, - ~[ ty::mk_f32(), ty::mk_i32() ], - ty::mk_f32()) - } - "powif64" => { - (0, - ~[ ty::mk_f64(), ty::mk_i32() ], - ty::mk_f64()) - } - "sinf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "sinf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "cosf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "cosf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "powf32" => { - (0, - ~[ ty::mk_f32(), ty::mk_f32() ], - ty::mk_f32()) - } - "powf64" => { - (0, - ~[ ty::mk_f64(), ty::mk_f64() ], - ty::mk_f64()) - } - "expf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "expf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "exp2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "exp2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "logf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "logf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "log10f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "log10f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "log2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "log2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "fmaf32" => { - (0, - ~[ ty::mk_f32(), ty::mk_f32(), ty::mk_f32() ], - ty::mk_f32()) - } - "fmaf64" => { - (0, - ~[ ty::mk_f64(), ty::mk_f64(), ty::mk_f64() ], - ty::mk_f64()) - } - "fabsf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "fabsf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "floorf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "floorf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "ceilf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "ceilf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "truncf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "truncf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "ctpop8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "ctpop16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "ctpop32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "ctpop64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "ctlz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "ctlz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "ctlz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "ctlz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "cttz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "cttz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "cttz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "cttz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "bswap16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "bswap32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "bswap64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - ref other => { - tcx.sess.span_err(it.span, - fmt!("unrecognized intrinsic function: `%s`", - *other)); - return; + }); + (0, ~[ td_ptr, visitor_object_ty ], ty::mk_nil()) + } + "frame_address" => { + let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy { + purity: ast::impure_fn, + sigil: ast::BorrowedSigil, + onceness: ast::Once, + region: ty::re_bound(ty::br_anon(0)), + bounds: ty::EmptyBuiltinBounds(), + sig: ty::FnSig { + bound_lifetime_names: opt_vec::Empty, + inputs: ~[ty::mk_imm_ptr(ccx.tcx, ty::mk_mach_uint(ast::ty_u8))], + output: ty::mk_nil() + } + }); + (0u, ~[fty], ty::mk_nil()) + } + "morestack_addr" => { + (0u, ~[], ty::mk_nil_ptr(ccx.tcx)) + } + "memcpy32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memcpy64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u64() + ], + ty::mk_nil()) + } + "memmove32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memmove64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u64() + ], + ty::mk_nil()) + } + "memset32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_u8(), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memset64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_u8(), + ty::mk_u64() + ], + ty::mk_nil()) + } + "sqrtf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "sqrtf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "powif32" => { + (0, + ~[ ty::mk_f32(), ty::mk_i32() ], + ty::mk_f32()) + } + "powif64" => { + (0, + ~[ ty::mk_f64(), ty::mk_i32() ], + ty::mk_f64()) + } + "sinf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "sinf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "cosf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "cosf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "powf32" => { + (0, + ~[ ty::mk_f32(), ty::mk_f32() ], + ty::mk_f32()) + } + "powf64" => { + (0, + ~[ ty::mk_f64(), ty::mk_f64() ], + ty::mk_f64()) + } + "expf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "expf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "exp2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "exp2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "logf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "logf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "log10f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "log10f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "log2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "log2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "fmaf32" => { + (0, + ~[ ty::mk_f32(), ty::mk_f32(), ty::mk_f32() ], + ty::mk_f32()) + } + "fmaf64" => { + (0, + ~[ ty::mk_f64(), ty::mk_f64(), ty::mk_f64() ], + ty::mk_f64()) + } + "fabsf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "fabsf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "floorf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "floorf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "ceilf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "ceilf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "truncf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "truncf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "ctpop8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "ctpop16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "ctpop32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "ctpop64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "ctlz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "ctlz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "ctlz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "ctlz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "cttz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "cttz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "cttz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "cttz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "bswap16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "bswap32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "bswap64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + ref other => { + tcx.sess.span_err(it.span, + fmt!("unrecognized intrinsic function: `%s`", + *other)); + return; + } } }; let fty = ty::mk_bare_fn(tcx, ty::BareFnTy { diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 908c5e23ab070..c9c441e8f6c83 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -42,22 +42,38 @@ pub extern "rust-intrinsic" { /// Atomic compare and exchange, release ordering. pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_cxchg_acqrel(dst: &mut int, old: int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_cxchg_relaxed(dst: &mut int, old: int, src: int) -> int; + + /// Atomic load, sequentially consistent. pub fn atomic_load(src: &int) -> int; /// Atomic load, acquire ordering. pub fn atomic_load_acq(src: &int) -> int; + #[cfg(not(stage0))] + pub fn atomic_load_relaxed(src: &int) -> int; + /// Atomic store, sequentially consistent. pub fn atomic_store(dst: &mut int, val: int); /// Atomic store, release ordering. pub fn atomic_store_rel(dst: &mut int, val: int); + #[cfg(not(stage0))] + pub fn atomic_store_relaxed(dst: &mut int, val: int); + /// Atomic exchange, sequentially consistent. pub fn atomic_xchg(dst: &mut int, src: int) -> int; /// Atomic exchange, acquire ordering. pub fn atomic_xchg_acq(dst: &mut int, src: int) -> int; /// Atomic exchange, release ordering. pub fn atomic_xchg_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xchg_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xchg_relaxed(dst: &mut int, src: int) -> int; /// Atomic addition, sequentially consistent. pub fn atomic_xadd(dst: &mut int, src: int) -> int; @@ -65,6 +81,10 @@ pub extern "rust-intrinsic" { pub fn atomic_xadd_acq(dst: &mut int, src: int) -> int; /// Atomic addition, release ordering. pub fn atomic_xadd_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xadd_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xadd_relaxed(dst: &mut int, src: int) -> int; /// Atomic subtraction, sequentially consistent. pub fn atomic_xsub(dst: &mut int, src: int) -> int; @@ -72,6 +92,98 @@ pub extern "rust-intrinsic" { pub fn atomic_xsub_acq(dst: &mut int, src: int) -> int; /// Atomic subtraction, release ordering. pub fn atomic_xsub_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xsub_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xsub_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_and(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_nand(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_or(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_xor(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_max(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_min(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_umin(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_umax(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umax_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umax_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int; /// The size of a type in bytes. ///