rustc: add new intrinsics - atomic_cxchg{_acq,_rel}

This commit is contained in:
Luqman Aden 2012-10-21 22:23:50 -04:00
parent 082d3d5167
commit e1db959ec2
9 changed files with 73 additions and 6 deletions

View File

@ -843,6 +843,9 @@ extern mod llvm {
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;

View 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 {

View 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),

View 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,

View File

@ -2605,7 +2605,15 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
}
~"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,

View 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,

View File

@ -84,6 +84,7 @@ LLVMArrayType
LLVMBasicBlockAsValue
LLVMBlockAddress
LLVMBuildAShr
LLVMBuildAtomicCmpXchg
LLVMBuildAtomicRMW
LLVMBuildAdd
LLVMBuildAggregateRet

View 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;

View 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;
@ -17,6 +21,15 @@ extern mod rusti {
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;