rustc: add new intrinsics - atomic_cxchg{_acq,_rel}
This commit is contained in:
parent
082d3d5167
commit
e1db959ec2
9 changed files with 73 additions and 6 deletions
|
@ -843,6 +843,9 @@ extern mod llvm {
|
||||||
Name: *c_char) -> ValueRef;
|
Name: *c_char) -> ValueRef;
|
||||||
|
|
||||||
/* Atomic Operations */
|
/* Atomic Operations */
|
||||||
|
fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
|
||||||
|
CMP: ValueRef, RHS: ValueRef,
|
||||||
|
++Order: AtomicOrdering) -> ValueRef;
|
||||||
fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
|
fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
|
||||||
LHS: ValueRef, RHS: ValueRef,
|
LHS: ValueRef, RHS: ValueRef,
|
||||||
++Order: AtomicOrdering) -> ValueRef;
|
++Order: AtomicOrdering) -> ValueRef;
|
||||||
|
|
|
@ -813,6 +813,11 @@ fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Atomic Operations
|
// 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,
|
fn AtomicRMW(cx: block, op: AtomicBinOp,
|
||||||
dst: ValueRef, src: ValueRef,
|
dst: ValueRef, src: ValueRef,
|
||||||
order: AtomicOrdering) -> 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));
|
Some(substs), Some(item.span));
|
||||||
let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
|
let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
|
||||||
match ccx.sess.str_of(item.ident) {
|
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" => {
|
~"atomic_xchg" => {
|
||||||
let old = AtomicRMW(bcx, Xchg,
|
let old = AtomicRMW(bcx, Xchg,
|
||||||
get_param(decl, first_real_arg),
|
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,
|
~"get_tydesc" | ~"needs_drop" => use_tydesc,
|
||||||
|
|
||||||
~"atomic_xchg" | ~"atomic_xadd" |
|
~"atomic_cxchg" | ~"atomic_cxchg_acq"|
|
||||||
~"atomic_xsub" | ~"atomic_xchg_acq" |
|
~"atomic_cxchg_rel"| ~"atomic_xchg" |
|
||||||
~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
|
~"atomic_xadd" | ~"atomic_xsub" |
|
||||||
~"atomic_xchg_rel" | ~"atomic_xadd_rel" |
|
~"atomic_xchg_acq" | ~"atomic_xadd_acq" |
|
||||||
~"atomic_xsub_rel" => 0,
|
~"atomic_xsub_acq" | ~"atomic_xchg_rel" |
|
||||||
|
~"atomic_xadd_rel" | ~"atomic_xsub_rel" => 0,
|
||||||
|
|
||||||
~"visit_tydesc" | ~"forget" | ~"addr_of" |
|
~"visit_tydesc" | ~"forget" | ~"addr_of" |
|
||||||
~"frame_address" | ~"morestack_addr" => 0,
|
~"frame_address" | ~"morestack_addr" => 0,
|
||||||
|
|
|
@ -2605,7 +2605,15 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
|
||||||
}
|
}
|
||||||
~"needs_drop" => (1u, ~[], ty::mk_bool(tcx)),
|
~"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_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
|
||||||
~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => {
|
~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => {
|
||||||
(0u, ~[arg(ast::by_copy,
|
(0u, ~[arg(ast::by_copy,
|
||||||
|
|
|
@ -482,6 +482,14 @@ extern "C" LLVMTypeRef LLVMMetadataType(void) {
|
||||||
return LLVMMetadataTypeInContext(LLVMGetGlobalContext());
|
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,
|
extern "C" LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,
|
||||||
AtomicRMWInst::BinOp op,
|
AtomicRMWInst::BinOp op,
|
||||||
LLVMValueRef target,
|
LLVMValueRef target,
|
||||||
|
|
|
@ -84,6 +84,7 @@ LLVMArrayType
|
||||||
LLVMBasicBlockAsValue
|
LLVMBasicBlockAsValue
|
||||||
LLVMBlockAddress
|
LLVMBlockAddress
|
||||||
LLVMBuildAShr
|
LLVMBuildAShr
|
||||||
|
LLVMBuildAtomicCmpXchg
|
||||||
LLVMBuildAtomicRMW
|
LLVMBuildAtomicRMW
|
||||||
LLVMBuildAdd
|
LLVMBuildAdd
|
||||||
LLVMBuildAggregateRet
|
LLVMBuildAggregateRet
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#[abi = "rust-intrinsic"]
|
#[abi = "rust-intrinsic"]
|
||||||
extern mod rusti {
|
extern mod rusti {
|
||||||
#[legacy_exports];
|
#[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(dst: &mut int, src: int) -> int;
|
||||||
fn atomic_xchg_acq(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;
|
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#[abi = "rust-intrinsic"]
|
#[abi = "rust-intrinsic"]
|
||||||
extern mod rusti {
|
extern mod rusti {
|
||||||
#[legacy_exports];
|
#[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(dst: &mut int, src: int) -> int;
|
||||||
fn atomic_xchg_acq(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;
|
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
|
||||||
|
@ -17,6 +21,15 @@ extern mod rusti {
|
||||||
fn main() {
|
fn main() {
|
||||||
let x = ~mut 1;
|
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 rusti::atomic_xchg(x, 0) == 1;
|
||||||
assert *x == 0;
|
assert *x == 0;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue