Skip to content

Commit e049a70

Browse files
committed
auto merge of #13693 : thestinger/rust/mem, r=alexcrichton
This exposes volatile versions of the memset/memmove/memcpy intrinsics. The volatile parameter must be constant, so this can't simply be a parameter to our intrinsics.
2 parents 1ce0b98 + b272472 commit e049a70

File tree

3 files changed

+43
-32
lines changed

3 files changed

+43
-32
lines changed

src/librustc/middle/trans/intrinsic.rs

+13-11
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ pub fn trans_intrinsic(ccx: &CrateContext,
129129
RetVoid(bcx);
130130
}
131131

132-
fn copy_intrinsic(bcx: &Block, allow_overlap: bool, tp_ty: ty::t) {
132+
fn copy_intrinsic(bcx: &Block, allow_overlap: bool, volatile: bool, tp_ty: ty::t) {
133133
let ccx = bcx.ccx();
134134
let lltp_ty = type_of::type_of(ccx, tp_ty);
135135
let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
@@ -154,13 +154,12 @@ pub fn trans_intrinsic(ccx: &CrateContext,
154154
let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p(ccx));
155155
let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p(ccx));
156156
let count = get_param(decl, first_real_arg + 2);
157-
let volatile = C_i1(ccx, false);
158157
let llfn = ccx.get_intrinsic(&name);
159-
Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile], []);
158+
Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
160159
RetVoid(bcx);
161160
}
162161

163-
fn memset_intrinsic(bcx: &Block, tp_ty: ty::t) {
162+
fn memset_intrinsic(bcx: &Block, volatile: bool, tp_ty: ty::t) {
164163
let ccx = bcx.ccx();
165164
let lltp_ty = type_of::type_of(ccx, tp_ty);
166165
let align = C_i32(ccx, machine::llalign_of_min(ccx, lltp_ty) as i32);
@@ -176,9 +175,8 @@ pub fn trans_intrinsic(ccx: &CrateContext,
176175
let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p(ccx));
177176
let val = get_param(decl, first_real_arg + 1);
178177
let count = get_param(decl, first_real_arg + 2);
179-
let volatile = C_i1(ccx, false);
180178
let llfn = ccx.get_intrinsic(&name);
181-
Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile], []);
179+
Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, C_i1(ccx, volatile)], []);
182180
RetVoid(bcx);
183181
}
184182

@@ -466,11 +464,15 @@ pub fn trans_intrinsic(ccx: &CrateContext,
466464
let lladdr = InBoundsGEP(bcx, ptr, [offset]);
467465
Ret(bcx, lladdr);
468466
}
469-
"copy_nonoverlapping_memory" => {
470-
copy_intrinsic(bcx, false, *substs.tys.get(0))
471-
}
472-
"copy_memory" => copy_intrinsic(bcx, true, *substs.tys.get(0)),
473-
"set_memory" => memset_intrinsic(bcx, *substs.tys.get(0)),
467+
"copy_nonoverlapping_memory" => copy_intrinsic(bcx, false, false, *substs.tys.get(0)),
468+
"copy_memory" => copy_intrinsic(bcx, true, false, *substs.tys.get(0)),
469+
"set_memory" => memset_intrinsic(bcx, false, *substs.tys.get(0)),
470+
471+
"volatile_copy_nonoverlapping_memory" =>
472+
copy_intrinsic(bcx, false, true, *substs.tys.get(0)),
473+
"volatile_copy_memory" => copy_intrinsic(bcx, true, true, *substs.tys.get(0)),
474+
"volatile_set_memory" => memset_intrinsic(bcx, true, *substs.tys.get(0)),
475+
474476
"ctlz8" => count_zeros_intrinsic(bcx, "llvm.ctlz.i8"),
475477
"ctlz16" => count_zeros_intrinsic(bcx, "llvm.ctlz.i16"),
476478
"ctlz32" => count_zeros_intrinsic(bcx, "llvm.ctlz.i32"),

src/librustc/middle/typeck/check/mod.rs

+3-17
Original file line numberDiff line numberDiff line change
@@ -4217,7 +4217,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
42174217
mutbl: ast::MutImmutable
42184218
}))
42194219
}
4220-
"copy_nonoverlapping_memory" => {
4220+
"copy_memory" | "copy_nonoverlapping_memory" |
4221+
"volatile_copy_memory" | "volatile_copy_nonoverlapping_memory" => {
42214222
(1,
42224223
vec!(
42234224
ty::mk_ptr(tcx, ty::mt {
@@ -4232,22 +4233,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
42324233
),
42334234
ty::mk_nil())
42344235
}
4235-
"copy_memory" => {
4236-
(1,
4237-
vec!(
4238-
ty::mk_ptr(tcx, ty::mt {
4239-
ty: param(ccx, 0),
4240-
mutbl: ast::MutMutable
4241-
}),
4242-
ty::mk_ptr(tcx, ty::mt {
4243-
ty: param(ccx, 0),
4244-
mutbl: ast::MutImmutable
4245-
}),
4246-
ty::mk_uint()
4247-
),
4248-
ty::mk_nil())
4249-
}
4250-
"set_memory" => {
4236+
"set_memory" | "volatile_set_memory" => {
42514237
(1,
42524238
vec!(
42534239
ty::mk_ptr(tcx, ty::mt {

src/libstd/intrinsics.rs

+27-4
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,6 @@ extern "rust-intrinsic" {
263263
/// Execute a breakpoint trap, for inspection by a debugger.
264264
pub fn breakpoint();
265265

266-
pub fn volatile_load<T>(src: *T) -> T;
267-
pub fn volatile_store<T>(dst: *mut T, val: T);
268-
269-
270266
/// The size of a type in bytes.
271267
///
272268
/// This is the exact number of bytes in memory taken up by a
@@ -340,6 +336,33 @@ extern "rust-intrinsic" {
340336
/// `min_align_of::<T>()`
341337
pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);
342338

339+
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
340+
/// a size of `count` * `size_of::<T>()` and an alignment of
341+
/// `min_align_of::<T>()`
342+
///
343+
/// The volatile parameter parameter is set to `true`, so it will not be optimized out.
344+
#[cfg(not(stage0))]
345+
pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *T, count: uint);
346+
/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
347+
/// a size of `count` * `size_of::<T>()` and an alignment of
348+
/// `min_align_of::<T>()`
349+
///
350+
/// The volatile parameter parameter is set to `true`, so it will not be optimized out.
351+
#[cfg(not(stage0))]
352+
pub fn volatile_copy_memory<T>(dst: *mut T, src: *T, count: uint);
353+
/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
354+
/// size of `count` * `size_of::<T>()` and an alignment of
355+
/// `min_align_of::<T>()`.
356+
///
357+
/// The volatile parameter parameter is set to `true`, so it will not be optimized out.
358+
#[cfg(not(stage0))]
359+
pub fn volatile_set_memory<T>(dst: *mut T, val: u8, count: uint);
360+
361+
/// Perform a volatile load from the `src` pointer.
362+
pub fn volatile_load<T>(src: *T) -> T;
363+
/// Perform a volatile store to the `dst` pointer.
364+
pub fn volatile_store<T>(dst: *mut T, val: T);
365+
343366
pub fn sqrtf32(x: f32) -> f32;
344367
pub fn sqrtf64(x: f64) -> f64;
345368

0 commit comments

Comments
 (0)