Skip to content

Commit befbd3a

Browse files
author
James Miller
committed
Add the rest of the atomic operations.
This makes the handling of atomic operations more generic, which does impose a specific naming convention for the intrinsics, but that seems ok with me, rather than having an individual case for each name. It also adds the intrinsics to the the intrinsics file.
1 parent fd83b92 commit befbd3a

File tree

4 files changed

+475
-396
lines changed

4 files changed

+475
-396
lines changed

src/librustc/middle/trans/foreign.rs

+65-111
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use core::prelude::*;
1212

1313
use back::{link, abi};
14-
use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg};
1514
use lib::llvm::{TypeRef, ValueRef};
1615
use lib;
1716
use middle::trans::base::*;
@@ -578,118 +577,73 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
578577
let mut bcx = top_scope_block(fcx, None);
579578
let lltop = bcx.llbb;
580579
let first_real_arg = fcx.arg_pos(0u);
581-
match ccx.sess.str_of(item.ident).as_slice() {
582-
"atomic_cxchg" => {
583-
let old = AtomicCmpXchg(bcx,
584-
get_param(decl, first_real_arg),
585-
get_param(decl, first_real_arg + 1u),
586-
get_param(decl, first_real_arg + 2u),
587-
SequentiallyConsistent);
588-
Store(bcx, old, fcx.llretptr.get());
589-
}
590-
"atomic_cxchg_acq" => {
591-
let old = AtomicCmpXchg(bcx,
592-
get_param(decl, first_real_arg),
593-
get_param(decl, first_real_arg + 1u),
594-
get_param(decl, first_real_arg + 2u),
595-
Acquire);
596-
Store(bcx, old, fcx.llretptr.get());
597-
}
598-
"atomic_cxchg_rel" => {
599-
let old = AtomicCmpXchg(bcx,
600-
get_param(decl, first_real_arg),
580+
581+
let nm = ccx.sess.str_of(item.ident);
582+
let name = nm.as_slice();
583+
584+
// This requires that atomic intrinsics follow a specific naming pattern:
585+
// "atomic_<operation>[_<ordering>], and no ordering means SeqCst
586+
if name.starts_with("atomic_") {
587+
let split : ~[&str] = name.split_iter('_').collect();
588+
assert!(split.len() >= 2, "Atomic intrinsic not correct format");
589+
let order = if split.len() == 2 {
590+
lib::llvm::SequentiallyConsistent
591+
} else {
592+
match split[2] {
593+
"relaxed" => lib::llvm::Monotonic,
594+
"acq" => lib::llvm::Acquire,
595+
"rel" => lib::llvm::Release,
596+
"acqrel" => lib::llvm::AcquireRelease,
597+
_ => ccx.sess.fatal("Unknown ordering in atomic intrinsic")
598+
}
599+
};
600+
601+
match split[1] {
602+
"cxchg" => {
603+
let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg),
604+
get_param(decl, first_real_arg + 1u),
605+
get_param(decl, first_real_arg + 2u),
606+
order);
607+
Store(bcx, old, fcx.llretptr.get());
608+
}
609+
"load" => {
610+
let old = AtomicLoad(bcx, get_param(decl, first_real_arg),
611+
order);
612+
Store(bcx, old, fcx.llretptr.get());
613+
}
614+
"store" => {
615+
AtomicStore(bcx, get_param(decl, first_real_arg + 1u),
616+
get_param(decl, first_real_arg),
617+
order);
618+
}
619+
op => {
620+
// These are all AtomicRMW ops
621+
let atom_op = match op {
622+
"xchg" => lib::llvm::Xchg,
623+
"xadd" => lib::llvm::Add,
624+
"xsub" => lib::llvm::Sub,
625+
"and" => lib::llvm::And,
626+
"nand" => lib::llvm::Nand,
627+
"or" => lib::llvm::Or,
628+
"xor" => lib::llvm::Xor,
629+
"max" => lib::llvm::Max,
630+
"min" => lib::llvm::Min,
631+
"umax" => lib::llvm::UMax,
632+
"umin" => lib::llvm::UMin,
633+
_ => ccx.sess.fatal("Unknown atomic operation")
634+
};
635+
636+
let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg),
601637
get_param(decl, first_real_arg + 1u),
602-
get_param(decl, first_real_arg + 2u),
603-
Release);
604-
Store(bcx, old, fcx.llretptr.get());
605-
}
606-
"atomic_load" => {
607-
let old = AtomicLoad(bcx,
608-
get_param(decl, first_real_arg),
609-
SequentiallyConsistent);
610-
Store(bcx, old, fcx.llretptr.get());
611-
}
612-
"atomic_load_acq" => {
613-
let old = AtomicLoad(bcx,
614-
get_param(decl, first_real_arg),
615-
Acquire);
616-
Store(bcx, old, fcx.llretptr.get());
617-
}
618-
"atomic_store" => {
619-
AtomicStore(bcx,
620-
get_param(decl, first_real_arg + 1u),
621-
get_param(decl, first_real_arg),
622-
SequentiallyConsistent);
623-
}
624-
"atomic_store_rel" => {
625-
AtomicStore(bcx,
626-
get_param(decl, first_real_arg + 1u),
627-
get_param(decl, first_real_arg),
628-
Release);
629-
}
630-
"atomic_xchg" => {
631-
let old = AtomicRMW(bcx, Xchg,
632-
get_param(decl, first_real_arg),
633-
get_param(decl, first_real_arg + 1u),
634-
SequentiallyConsistent);
635-
Store(bcx, old, fcx.llretptr.get());
636-
}
637-
"atomic_xchg_acq" => {
638-
let old = AtomicRMW(bcx, Xchg,
639-
get_param(decl, first_real_arg),
640-
get_param(decl, first_real_arg + 1u),
641-
Acquire);
642-
Store(bcx, old, fcx.llretptr.get());
643-
}
644-
"atomic_xchg_rel" => {
645-
let old = AtomicRMW(bcx, Xchg,
646-
get_param(decl, first_real_arg),
647-
get_param(decl, first_real_arg + 1u),
648-
Release);
649-
Store(bcx, old, fcx.llretptr.get());
650-
}
651-
"atomic_xadd" => {
652-
let old = AtomicRMW(bcx, lib::llvm::Add,
653-
get_param(decl, first_real_arg),
654-
get_param(decl, first_real_arg + 1u),
655-
SequentiallyConsistent);
656-
Store(bcx, old, fcx.llretptr.get());
657-
}
658-
"atomic_xadd_acq" => {
659-
let old = AtomicRMW(bcx, lib::llvm::Add,
660-
get_param(decl, first_real_arg),
661-
get_param(decl, first_real_arg + 1u),
662-
Acquire);
663-
Store(bcx, old, fcx.llretptr.get());
664-
}
665-
"atomic_xadd_rel" => {
666-
let old = AtomicRMW(bcx, lib::llvm::Add,
667-
get_param(decl, first_real_arg),
668-
get_param(decl, first_real_arg + 1u),
669-
Release);
670-
Store(bcx, old, fcx.llretptr.get());
671-
}
672-
"atomic_xsub" => {
673-
let old = AtomicRMW(bcx, lib::llvm::Sub,
674-
get_param(decl, first_real_arg),
675-
get_param(decl, first_real_arg + 1u),
676-
SequentiallyConsistent);
677-
Store(bcx, old, fcx.llretptr.get());
678-
}
679-
"atomic_xsub_acq" => {
680-
let old = AtomicRMW(bcx, lib::llvm::Sub,
681-
get_param(decl, first_real_arg),
682-
get_param(decl, first_real_arg + 1u),
683-
Acquire);
684-
Store(bcx, old, fcx.llretptr.get());
685-
}
686-
"atomic_xsub_rel" => {
687-
let old = AtomicRMW(bcx, lib::llvm::Sub,
688-
get_param(decl, first_real_arg),
689-
get_param(decl, first_real_arg + 1u),
690-
Release);
691-
Store(bcx, old, fcx.llretptr.get());
638+
order);
639+
Store(bcx, old, fcx.llretptr.get());
640+
}
692641
}
642+
643+
return;
644+
}
645+
646+
match name {
693647
"size_of" => {
694648
let tp_ty = substs.tys[0];
695649
let lltp_ty = type_of::type_of(ccx, tp_ty);

src/librustc/middle/trans/type_use.rs

+37-40
Original file line numberDiff line numberDiff line change
@@ -117,46 +117,43 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint)
117117
_,
118118
_) => {
119119
if abi.is_intrinsic() {
120-
let flags = match cx.ccx.sess.str_of(i.ident).as_slice() {
121-
"size_of" | "pref_align_of" | "min_align_of" |
122-
"uninit" | "init" | "transmute" | "move_val" |
123-
"move_val_init" => use_repr,
124-
125-
"get_tydesc" | "needs_drop" => use_tydesc,
126-
127-
"atomic_cxchg" | "atomic_cxchg_acq"|
128-
"atomic_cxchg_rel"| "atomic_load" |
129-
"atomic_load_acq" | "atomic_store" |
130-
"atomic_store_rel"| "atomic_xchg" |
131-
"atomic_xadd" | "atomic_xsub" |
132-
"atomic_xchg_acq" | "atomic_xadd_acq" |
133-
"atomic_xsub_acq" | "atomic_xchg_rel" |
134-
"atomic_xadd_rel" | "atomic_xsub_rel" => 0,
135-
136-
"visit_tydesc" | "forget" | "frame_address" |
137-
"morestack_addr" => 0,
138-
139-
"memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
140-
"memset32" | "memset64" => use_repr,
141-
142-
"sqrtf32" | "sqrtf64" | "powif32" | "powif64" |
143-
"sinf32" | "sinf64" | "cosf32" | "cosf64" |
144-
"powf32" | "powf64" | "expf32" | "expf64" |
145-
"exp2f32" | "exp2f64" | "logf32" | "logf64" |
146-
"log10f32"| "log10f64"| "log2f32" | "log2f64" |
147-
"fmaf32" | "fmaf64" | "fabsf32" | "fabsf64" |
148-
"floorf32"| "floorf64"| "ceilf32" | "ceilf64" |
149-
"truncf32"| "truncf64" => 0,
150-
151-
"ctpop8" | "ctpop16" | "ctpop32" | "ctpop64" => 0,
152-
153-
"ctlz8" | "ctlz16" | "ctlz32" | "ctlz64" => 0,
154-
"cttz8" | "cttz16" | "cttz32" | "cttz64" => 0,
155-
156-
"bswap16" | "bswap32" | "bswap64" => 0,
157-
158-
// would be cool to make these an enum instead of strings!
159-
_ => fail!("unknown intrinsic in type_use")
120+
let nm = cx.ccx.sess.str_of(i.ident);
121+
let name = nm.as_slice();
122+
let flags = if name.starts_with("atomic_") {
123+
0
124+
} else {
125+
match name {
126+
"size_of" | "pref_align_of" | "min_align_of" |
127+
"uninit" | "init" | "transmute" | "move_val" |
128+
"move_val_init" => use_repr,
129+
130+
"get_tydesc" | "needs_drop" => use_tydesc,
131+
132+
"visit_tydesc" | "forget" | "frame_address" |
133+
"morestack_addr" => 0,
134+
135+
"memcpy32" | "memcpy64" | "memmove32" | "memmove64" |
136+
"memset32" | "memset64" => use_repr,
137+
138+
"sqrtf32" | "sqrtf64" | "powif32" | "powif64" |
139+
"sinf32" | "sinf64" | "cosf32" | "cosf64" |
140+
"powf32" | "powf64" | "expf32" | "expf64" |
141+
"exp2f32" | "exp2f64" | "logf32" | "logf64" |
142+
"log10f32"| "log10f64"| "log2f32" | "log2f64" |
143+
"fmaf32" | "fmaf64" | "fabsf32" | "fabsf64" |
144+
"floorf32"| "floorf64"| "ceilf32" | "ceilf64" |
145+
"truncf32"| "truncf64" => 0,
146+
147+
"ctpop8" | "ctpop16" | "ctpop32" | "ctpop64" => 0,
148+
149+
"ctlz8" | "ctlz16" | "ctlz32" | "ctlz64" => 0,
150+
"cttz8" | "cttz16" | "cttz32" | "cttz64" => 0,
151+
152+
"bswap16" | "bswap32" | "bswap64" => 0,
153+
154+
// would be cool to make these an enum instead of strings!
155+
_ => fail!("unknown intrinsic in type_use")
156+
}
160157
};
161158
for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;}
162159
}

0 commit comments

Comments
 (0)