rustc: add new intrinsics - atomic_cxchg{_acq,_rel}
This commit is contained in:
parent
082d3d5167
commit
e1db959ec2
@ -843,6 +843,9 @@ fn LLVMBuildPtrDiff(B: BuilderRef, LHS: ValueRef, RHS: ValueRef,
|
||||
Name: *c_char) -> ValueRef;
|
||||
|
||||
/* Atomic Operations */
|
||||
fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
|
||||
CMP: ValueRef, RHS: ValueRef,
|
||||
++Order: AtomicOrdering) -> ValueRef;
|
||||
fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
|
||||
LHS: ValueRef, RHS: ValueRef,
|
||||
++Order: AtomicOrdering) -> ValueRef;
|
||||
|
@ -813,6 +813,11 @@ fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
|
||||
}
|
||||
|
||||
// Atomic Operations
|
||||
fn AtomicCmpXchg(cx: block, dst: ValueRef,
|
||||
cmp: ValueRef, src: ValueRef,
|
||||
order: AtomicOrdering) -> ValueRef {
|
||||
llvm::LLVMBuildAtomicCmpXchg(B(cx), dst, cmp, src, order)
|
||||
}
|
||||
fn AtomicRMW(cx: block, op: AtomicBinOp,
|
||||
dst: ValueRef, src: ValueRef,
|
||||
order: AtomicOrdering) -> ValueRef {
|
||||
|
@ -799,6 +799,30 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
||||
Some(substs), Some(item.span));
|
||||
let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
|
||||
match ccx.sess.str_of(item.ident) {
|
||||
~"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);
|
||||
}
|
||||
~"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);
|
||||
}
|
||||
~"atomic_cxchg_rel" => {
|
||||
let old = AtomicCmpXchg(bcx,
|
||||
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);
|
||||
}
|
||||
~"atomic_xchg" => {
|
||||
let old = AtomicRMW(bcx, Xchg,
|
||||
get_param(decl, first_real_arg),
|
||||
|
@ -98,11 +98,12 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
|
||||
|
||||
~"get_tydesc" | ~"needs_drop" => use_tydesc,
|
||||
|
||||
~"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,
|
||||
~"atomic_cxchg" | ~"atomic_cxchg_acq"|
|
||||
~"atomic_cxchg_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" | ~"addr_of" |
|
||||
~"frame_address" | ~"morestack_addr" => 0,
|
||||
|
@ -2605,7 +2605,15 @@ fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
|
||||
}
|
||||
~"needs_drop" => (1u, ~[], ty::mk_bool(tcx)),
|
||||
|
||||
~"atomic_xchg" | ~"atomic_xadd" | ~"atomic_xsub" |
|
||||
~"atomic_cxchg" | ~"atomic_cxchg_acq"| ~"atomic_cxchg_rel" => {
|
||||
(0u, ~[arg(ast::by_copy,
|
||||
ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
|
||||
ty::mk_int(tcx))),
|
||||
arg(ast::by_copy, ty::mk_int(tcx)),
|
||||
arg(ast::by_copy, ty::mk_int(tcx))],
|
||||
ty::mk_int(tcx))
|
||||
}
|
||||
~"atomic_xchg" | ~"atomic_xadd" | ~"atomic_xsub" |
|
||||
~"atomic_xchg_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
|
||||
~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => {
|
||||
(0u, ~[arg(ast::by_copy,
|
||||
|
@ -482,6 +482,14 @@ extern "C" LLVMTypeRef LLVMMetadataType(void) {
|
||||
return LLVMMetadataTypeInContext(LLVMGetGlobalContext());
|
||||
}
|
||||
|
||||
extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
|
||||
LLVMValueRef target,
|
||||
LLVMValueRef old,
|
||||
LLVMValueRef source,
|
||||
AtomicOrdering order) {
|
||||
return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
|
||||
unwrap(source), order));
|
||||
}
|
||||
extern "C" LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,
|
||||
AtomicRMWInst::BinOp op,
|
||||
LLVMValueRef target,
|
||||
|
@ -84,6 +84,7 @@ LLVMArrayType
|
||||
LLVMBasicBlockAsValue
|
||||
LLVMBlockAddress
|
||||
LLVMBuildAShr
|
||||
LLVMBuildAtomicCmpXchg
|
||||
LLVMBuildAtomicRMW
|
||||
LLVMBuildAdd
|
||||
LLVMBuildAggregateRet
|
||||
|
@ -2,6 +2,10 @@
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern mod rusti {
|
||||
#[legacy_exports];
|
||||
fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
|
||||
fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
|
||||
fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
|
||||
|
||||
fn atomic_xchg(dst: &mut int, src: int) -> int;
|
||||
fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
|
||||
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
|
||||
|
@ -1,6 +1,10 @@
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern mod rusti {
|
||||
#[legacy_exports];
|
||||
fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
|
||||
fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
|
||||
fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
|
||||
|
||||
fn atomic_xchg(dst: &mut int, src: int) -> int;
|
||||
fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
|
||||
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
|
||||
@ -17,6 +21,15 @@
|
||||
fn main() {
|
||||
let x = ~mut 1;
|
||||
|
||||
assert rusti::atomic_cxchg(x, 1, 2) == 1;
|
||||
assert *x == 2;
|
||||
|
||||
assert rusti::atomic_cxchg_acq(x, 1, 3) == 2;
|
||||
assert *x == 2;
|
||||
|
||||
assert rusti::atomic_cxchg_rel(x, 2, 1) == 2;
|
||||
assert *x == 1;
|
||||
|
||||
assert rusti::atomic_xchg(x, 0) == 1;
|
||||
assert *x == 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user