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;
}
// 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 {
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),
~"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,
}
~"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,
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,
LLVMBasicBlockAsValue
LLVMBlockAddress
LLVMBuildAShr
+LLVMBuildAtomicCmpXchg
LLVMBuildAtomicRMW
LLVMBuildAdd
LLVMBuildAggregateRet
#[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;
#[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;
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;