Skip to content

Commit e1db959

Browse files
committed
rustc: add new intrinsics - atomic_cxchg{_acq,_rel}
1 parent 082d3d5 commit e1db959

File tree

9 files changed

+73
-6
lines changed

9 files changed

+73
-6
lines changed

src/rustc/lib/llvm.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -843,6 +843,9 @@ extern mod llvm {
843843
Name: *c_char) -> ValueRef;
844844

845845
/* Atomic Operations */
846+
fn LLVMBuildAtomicCmpXchg(B: BuilderRef, LHS: ValueRef,
847+
CMP: ValueRef, RHS: ValueRef,
848+
++Order: AtomicOrdering) -> ValueRef;
846849
fn LLVMBuildAtomicRMW(B: BuilderRef, ++Op: AtomicBinOp,
847850
LHS: ValueRef, RHS: ValueRef,
848851
++Order: AtomicOrdering) -> ValueRef;

src/rustc/middle/trans/build.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,11 @@ fn Resume(cx: block, Exn: ValueRef) -> ValueRef {
813813
}
814814

815815
// Atomic Operations
816+
fn AtomicCmpXchg(cx: block, dst: ValueRef,
817+
cmp: ValueRef, src: ValueRef,
818+
order: AtomicOrdering) -> ValueRef {
819+
llvm::LLVMBuildAtomicCmpXchg(B(cx), dst, cmp, src, order)
820+
}
816821
fn AtomicRMW(cx: block, op: AtomicBinOp,
817822
dst: ValueRef, src: ValueRef,
818823
order: AtomicOrdering) -> ValueRef {

src/rustc/middle/trans/foreign.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,30 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
799799
Some(substs), Some(item.span));
800800
let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb;
801801
match ccx.sess.str_of(item.ident) {
802+
~"atomic_cxchg" => {
803+
let old = AtomicCmpXchg(bcx,
804+
get_param(decl, first_real_arg),
805+
get_param(decl, first_real_arg + 1u),
806+
get_param(decl, first_real_arg + 2u),
807+
SequentiallyConsistent);
808+
Store(bcx, old, fcx.llretptr);
809+
}
810+
~"atomic_cxchg_acq" => {
811+
let old = AtomicCmpXchg(bcx,
812+
get_param(decl, first_real_arg),
813+
get_param(decl, first_real_arg + 1u),
814+
get_param(decl, first_real_arg + 2u),
815+
Acquire);
816+
Store(bcx, old, fcx.llretptr);
817+
}
818+
~"atomic_cxchg_rel" => {
819+
let old = AtomicCmpXchg(bcx,
820+
get_param(decl, first_real_arg),
821+
get_param(decl, first_real_arg + 1u),
822+
get_param(decl, first_real_arg + 2u),
823+
Release);
824+
Store(bcx, old, fcx.llretptr);
825+
}
802826
~"atomic_xchg" => {
803827
let old = AtomicRMW(bcx, Xchg,
804828
get_param(decl, first_real_arg),

src/rustc/middle/trans/type_use.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,12 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
9898

9999
~"get_tydesc" | ~"needs_drop" => use_tydesc,
100100

101-
~"atomic_xchg" | ~"atomic_xadd" |
102-
~"atomic_xsub" | ~"atomic_xchg_acq" |
103-
~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
104-
~"atomic_xchg_rel" | ~"atomic_xadd_rel" |
105-
~"atomic_xsub_rel" => 0,
101+
~"atomic_cxchg" | ~"atomic_cxchg_acq"|
102+
~"atomic_cxchg_rel"| ~"atomic_xchg" |
103+
~"atomic_xadd" | ~"atomic_xsub" |
104+
~"atomic_xchg_acq" | ~"atomic_xadd_acq" |
105+
~"atomic_xsub_acq" | ~"atomic_xchg_rel" |
106+
~"atomic_xadd_rel" | ~"atomic_xsub_rel" => 0,
106107

107108
~"visit_tydesc" | ~"forget" | ~"addr_of" |
108109
~"frame_address" | ~"morestack_addr" => 0,

src/rustc/middle/typeck/check.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2605,7 +2605,15 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
26052605
}
26062606
~"needs_drop" => (1u, ~[], ty::mk_bool(tcx)),
26072607
2608-
~"atomic_xchg" | ~"atomic_xadd" | ~"atomic_xsub" |
2608+
~"atomic_cxchg" | ~"atomic_cxchg_acq"| ~"atomic_cxchg_rel" => {
2609+
(0u, ~[arg(ast::by_copy,
2610+
ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
2611+
ty::mk_int(tcx))),
2612+
arg(ast::by_copy, ty::mk_int(tcx)),
2613+
arg(ast::by_copy, ty::mk_int(tcx))],
2614+
ty::mk_int(tcx))
2615+
}
2616+
~"atomic_xchg" | ~"atomic_xadd" | ~"atomic_xsub" |
26092617
~"atomic_xchg_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
26102618
~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" => {
26112619
(0u, ~[arg(ast::by_copy,

src/rustllvm/RustWrapper.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,14 @@ extern "C" LLVMTypeRef LLVMMetadataType(void) {
482482
return LLVMMetadataTypeInContext(LLVMGetGlobalContext());
483483
}
484484

485+
extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
486+
LLVMValueRef target,
487+
LLVMValueRef old,
488+
LLVMValueRef source,
489+
AtomicOrdering order) {
490+
return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
491+
unwrap(source), order));
492+
}
485493
extern "C" LLVMValueRef LLVMBuildAtomicRMW(LLVMBuilderRef B,
486494
AtomicRMWInst::BinOp op,
487495
LLVMValueRef target,

src/rustllvm/rustllvm.def.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ LLVMArrayType
8484
LLVMBasicBlockAsValue
8585
LLVMBlockAddress
8686
LLVMBuildAShr
87+
LLVMBuildAtomicCmpXchg
8788
LLVMBuildAtomicRMW
8889
LLVMBuildAdd
8990
LLVMBuildAggregateRet

src/test/auxiliary/cci_intrinsic.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
#[abi = "rust-intrinsic"]
33
extern mod rusti {
44
#[legacy_exports];
5+
fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
6+
fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
7+
fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
8+
59
fn atomic_xchg(dst: &mut int, src: int) -> int;
610
fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
711
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;

src/test/run-pass/intrinsic-atomics.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#[abi = "rust-intrinsic"]
22
extern mod rusti {
33
#[legacy_exports];
4+
fn atomic_cxchg(dst: &mut int, old: int, src: int) -> int;
5+
fn atomic_cxchg_acq(dst: &mut int, old: int, src: int) -> int;
6+
fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int;
7+
48
fn atomic_xchg(dst: &mut int, src: int) -> int;
59
fn atomic_xchg_acq(dst: &mut int, src: int) -> int;
610
fn atomic_xchg_rel(dst: &mut int, src: int) -> int;
@@ -17,6 +21,15 @@ extern mod rusti {
1721
fn main() {
1822
let x = ~mut 1;
1923

24+
assert rusti::atomic_cxchg(x, 1, 2) == 1;
25+
assert *x == 2;
26+
27+
assert rusti::atomic_cxchg_acq(x, 1, 3) == 2;
28+
assert *x == 2;
29+
30+
assert rusti::atomic_cxchg_rel(x, 2, 1) == 2;
31+
assert *x == 1;
32+
2033
assert rusti::atomic_xchg(x, 0) == 1;
2134
assert *x == 0;
2235

0 commit comments

Comments
 (0)