From 67966fa9de062cfe05604ed7e11e9ab58bb55225 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Sun, 3 Nov 2013 16:54:58 -0500 Subject: simplify memcpy/memmove/memset intrinsics This moves the per-architecture difference into the compiler. --- src/libstd/cast.rs | 15 ++---------- src/libstd/ptr.rs | 48 ++++++++++++++++++++++++++++++++++----- src/libstd/unstable/intrinsics.rs | 15 ++++++++++++ 3 files changed, 59 insertions(+), 19 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/cast.rs b/src/libstd/cast.rs index a4f2ee0d09c..05a72dc4109 100644 --- a/src/libstd/cast.rs +++ b/src/libstd/cast.rs @@ -13,26 +13,15 @@ use ptr::RawPtr; use mem; use unstable::intrinsics; +use ptr::copy_nonoverlapping_memory; /// Casts the value at `src` to U. The two types must have the same length. -#[cfg(target_word_size = "32")] #[inline] pub unsafe fn transmute_copy(src: &T) -> U { let mut dest: U = intrinsics::uninit(); let dest_ptr: *mut u8 = transmute(&mut dest); let src_ptr: *u8 = transmute(src); - intrinsics::memcpy32(dest_ptr, src_ptr, mem::size_of::() as u32); - dest -} - -/// Casts the value at `src` to U. The two types must have the same length. -#[cfg(target_word_size = "64")] -#[inline] -pub unsafe fn transmute_copy(src: &T) -> U { - let mut dest: U = intrinsics::uninit(); - let dest_ptr: *mut u8 = transmute(&mut dest); - let src_ptr: *u8 = transmute(src); - intrinsics::memcpy64(dest_ptr, src_ptr, mem::size_of::() as u64); + copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::()); dest } diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 376d178f8f7..65ae9f40403 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -87,7 +87,7 @@ pub fn is_not_null>(ptr: P) -> bool { ptr.is_not_null() } * and destination may overlap. */ #[inline] -#[cfg(target_word_size = "32")] +#[cfg(target_word_size = "32", stage0)] pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { intrinsics::memmove32(dst, cast::transmute_immut_unsafe(src), @@ -101,13 +101,25 @@ pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { * and destination may overlap. */ #[inline] -#[cfg(target_word_size = "64")] +#[cfg(target_word_size = "64", stage0)] pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { intrinsics::memmove64(dst, cast::transmute_immut_unsafe(src), count as u64); } +/** + * Copies data from one location to another. + * + * Copies `count` elements (not bytes) from `src` to `dst`. The source + * and destination may overlap. + */ +#[inline] +#[cfg(not(stage0))] +pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { + intrinsics::copy_memory(dst, cast::transmute_immut_unsafe(src), count) +} + /** * Copies data from one location to another. * @@ -115,7 +127,7 @@ pub unsafe fn copy_memory>(dst: *mut T, src: P, count: uint) { * and destination may *not* overlap. */ #[inline] -#[cfg(target_word_size = "32")] +#[cfg(target_word_size = "32", stage0)] pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, src: P, count: uint) { @@ -131,7 +143,7 @@ pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, * and destination may *not* overlap. */ #[inline] -#[cfg(target_word_size = "64")] +#[cfg(target_word_size = "64", stage0)] pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, src: P, count: uint) { @@ -140,12 +152,26 @@ pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, count as u64); } +/** + * Copies data from one location to another. + * + * Copies `count` elements (not bytes) from `src` to `dst`. The source + * and destination may *not* overlap. + */ +#[inline] +#[cfg(not(stage0))] +pub unsafe fn copy_nonoverlapping_memory>(dst: *mut T, + src: P, + count: uint) { + intrinsics::copy_nonoverlapping_memory(dst, cast::transmute_immut_unsafe(src), count) +} + /** * Invokes memset on the specified pointer, setting `count * size_of::()` * bytes of memory starting at `dst` to `c`. */ #[inline] -#[cfg(target_word_size = "32")] +#[cfg(target_word_size = "32", stage0)] pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { intrinsics::memset32(dst, c, count as u32); } @@ -155,11 +181,21 @@ pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { * bytes of memory starting at `dst` to `c`. */ #[inline] -#[cfg(target_word_size = "64")] +#[cfg(target_word_size = "64", stage0)] pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { intrinsics::memset64(dst, c, count as u64); } +/** + * Invokes memset on the specified pointer, setting `count * size_of::()` + * bytes of memory starting at `dst` to `c`. + */ +#[inline] +#[cfg(not(stage0))] +pub unsafe fn set_memory(dst: *mut T, c: u8, count: uint) { + intrinsics::set_memory(dst, c, count) +} + /** * Zeroes out `count * size_of::` bytes of memory at `dst` */ diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 9d3e3446a4b..c086e13d740 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -345,25 +345,40 @@ extern "rust-intrinsic" { /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` + #[cfg(stage0)] pub fn memcpy32(dst: *mut T, src: *T, count: u32); /// Equivalent to the `llvm.memcpy.p0i8.0i8.i64` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` + #[cfg(stage0)] pub fn memcpy64(dst: *mut T, src: *T, count: u64); /// Equivalent to the `llvm.memmove.p0i8.0i8.i32` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` + #[cfg(stage0)] pub fn memmove32(dst: *mut T, src: *T, count: u32); /// Equivalent to the `llvm.memmove.p0i8.0i8.i64` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` + #[cfg(stage0)] pub fn memmove64(dst: *mut T, src: *T, count: u64); /// Equivalent to the `llvm.memset.p0i8.i32` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` + #[cfg(stage0)] pub fn memset32(dst: *mut T, val: u8, count: u32); /// Equivalent to the `llvm.memset.p0i8.i64` intrinsic, with a size of /// `count` * `size_of::()` and an alignment of `min_align_of::()` + #[cfg(stage0)] pub fn memset64(dst: *mut T, val: u8, count: u64); + #[cfg(not(stage0))] + pub fn copy_nonoverlapping_memory(dst: *mut T, src: *T, count: uint); + + #[cfg(not(stage0))] + pub fn copy_memory(dst: *mut T, src: *T, count: uint); + + #[cfg(not(stage0))] + pub fn set_memory(dst: *mut T, val: u8, count: uint); + pub fn sqrtf32(x: f32) -> f32; pub fn sqrtf64(x: f64) -> f64; -- cgit 1.4.1-3-g733a5