]> git.lizzy.rs Git - rust.git/commitdiff
rustc: add new intrinsics - atomic_cxchg{_acq,_rel}
authorLuqman Aden <laden@csclub.uwaterloo.ca>
Mon, 22 Oct 2012 02:23:50 +0000 (22:23 -0400)
committerLuqman Aden <laden@csclub.uwaterloo.ca>
Mon, 22 Oct 2012 02:23:50 +0000 (22:23 -0400)
src/rustc/lib/llvm.rs
src/rustc/middle/trans/build.rs
src/rustc/middle/trans/foreign.rs
src/rustc/middle/trans/type_use.rs
src/rustc/middle/typeck/check.rs
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.def.in
src/test/auxiliary/cci_intrinsic.rs
src/test/run-pass/intrinsic-atomics.rs

index 0d92c19b9521b9163c3773bda44a4c6a31e28c18..f1397006b16b958d61ec1ebd3b3c1d065fcea09e 100644 (file)
@@ -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;
index ea992600ae19b7a537f7ae1f865c366e20589aa4..f7690b7bc93004dd38fa05a75bc766a38c4bfb28 100644 (file)
@@ -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 {
index d307fcb5dca0fb0b271cb02f9140cbc8ec2011a8..8fa23ef8fabd8ce2e7de9f43c07dae434914bd65 100644 (file)
@@ -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),
index 8b2efacd4d16a6da4cebd4e86c727c9c0e0c6c3e..ddd50d47c08fd116fb7cec9ee701a184ca4274c4 100644 (file)
@@ -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,
index 5f9e584fa7b99b8d2bcbe12578ab5981f391f4ae..f4764c5d595d816a129234c2a01f96c717a4825e 100644 (file)
@@ -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,
index 498a4e137f0e38de6cdd85142fdf90a0d63b46a3..39a707ad3206c64022f5403e7b68a45adf03213c 100644 (file)
@@ -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,
index 36833e5175e6d193014287c8131ee58dbe7c7f2f..44636f4f36b16c1c2d7e63cda5db796d8f2142ac 100644 (file)
@@ -84,6 +84,7 @@ LLVMArrayType
 LLVMBasicBlockAsValue
 LLVMBlockAddress
 LLVMBuildAShr
+LLVMBuildAtomicCmpXchg
 LLVMBuildAtomicRMW
 LLVMBuildAdd
 LLVMBuildAggregateRet
index 1cde1a049fe63eff90b7fd9d45b20ecc5d49ff51..f3ea9fd531c38a2992cd9d087ccba3848c3403b2 100644 (file)
@@ -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;
index 2629afa4909fb914e13ba8546d5ec8a3a790f060..8438ecf383ec13c75199564d073876310311130a 100644 (file)
@@ -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;
 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;