diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2013-05-24 13:58:55 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2013-05-26 10:26:03 -0400 |
| commit | cf8e9f9aec25b6441d3198d7ddb4bd6a6b9e1475 (patch) | |
| tree | d6e7e72c11ed6ab0c10a8210596af1d530069007 /src/libstd | |
| parent | f254d119eab514c91fbd6590fba821ec7a0bfd7f (diff) | |
| download | rust-cf8e9f9aec25b6441d3198d7ddb4bd6a6b9e1475.tar.gz rust-cf8e9f9aec25b6441d3198d7ddb4bd6a6b9e1475.zip | |
make the memcpy/memmove intrinsics higher-level
This allows them to make use of the type's alignment, instead of being pessimistic and assuming it is only 1.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/ptr.rs | 60 | ||||
| -rw-r--r-- | src/libstd/unstable/intrinsics.rs | 21 |
2 files changed, 58 insertions, 23 deletions
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index d1c0ffe7953..97a7d0e11a6 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -27,12 +27,6 @@ pub mod libc_ { #[abi = "cdecl"] pub extern { #[rust_stack] - unsafe fn memmove(dest: *mut c_void, - src: *const c_void, - n: libc::size_t) - -> *c_void; - - #[rust_stack] unsafe fn memset(dest: *mut c_void, c: libc::c_int, len: libc::size_t) @@ -97,15 +91,28 @@ pub fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) } * and destination may overlap. */ #[inline(always)] -#[cfg(target_word_size = "32")] +#[cfg(target_word_size = "32", stage0)] pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove32; let n = count * sys::size_of::<T>(); memmove32(dst as *mut u8, src as *u8, n as u32); } +/** + * Copies data from one location to another + * + * Copies `count` elements (not bytes) from `src` to `dst`. The source + * and destination may overlap. + */ +#[inline(always)] +#[cfg(target_word_size = "32", not(stage0))] +pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { + use unstable::intrinsics::memmove32; + memmove32(dst, src, count as u32); +} + #[inline(always)] -#[cfg(target_word_size = "64")] +#[cfg(target_word_size = "64", stage0)] pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { use unstable::intrinsics::memmove64; let n = count * sys::size_of::<T>(); @@ -113,25 +120,40 @@ pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { } #[inline(always)] -#[cfg(target_word_size = "32")] +#[cfg(target_word_size = "64", not(stage0))] +pub unsafe fn copy_memory<T>(dst: *mut T, src: *const T, count: uint) { + use unstable::intrinsics::memmove64; + memmove64(dst, src as *T, count as u64); +} + +#[inline(always)] +#[cfg(target_word_size = "32", stage0)] +pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) { + use unstable::intrinsics::memmove32; + let n = count * sys::size_of::<T>(); + memmove32(dst as *mut u8, src as *u8, n as u32); +} + +#[inline(always)] +#[cfg(target_word_size = "32", not(stage0))] pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) { - #[cfg(stage0)] - use memcpy32 = unstable::intrinsics::memmove32; - #[cfg(not(stage0))] use unstable::intrinsics::memcpy32; + memcpy32(dst, src as *T, count as u32); +} + +#[inline(always)] +#[cfg(target_word_size = "64", stage0)] +pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) { + use unstable::intrinsics::memmove64; let n = count * sys::size_of::<T>(); - memcpy32(dst as *mut u8, src as *u8, n as u32); + memmove64(dst as *mut u8, src as *u8, n as u64); } #[inline(always)] -#[cfg(target_word_size = "64")] +#[cfg(target_word_size = "64", not(stage0))] pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: uint) { - #[cfg(stage0)] - use memcpy64 = unstable::intrinsics::memmove64; - #[cfg(not(stage0))] use unstable::intrinsics::memcpy64; - let n = count * sys::size_of::<T>(); - memcpy64(dst as *mut u8, src as *u8, n as u64); + memcpy64(dst, src as *T, count as u64); } #[inline(always)] diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 521708621fc..c0975d6a526 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -127,18 +127,31 @@ pub extern "rust-intrinsic" { /// Get the address of the `__morestack` stack growth function. pub fn morestack_addr() -> *(); - /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic. + /// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of + /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()` #[cfg(not(stage0))] - pub fn memcpy32(dst: *mut u8, src: *u8, size: u32); - /// Equivalent to the `llvm.memcpy.p0i8.0i8.i64` intrinsic. + pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32); + /// Equivalent to the `llvm.memcpy.p0i8.0i8.i64` intrinsic, with a size of + /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()` #[cfg(not(stage0))] - pub fn memcpy64(dst: *mut u8, src: *u8, size: u64); + pub fn memcpy64<T>(dst: *mut T, src: *T, count: u64); /// Equivalent to the `llvm.memmove.p0i8.0i8.i32` intrinsic. + #[cfg(stage0)] pub fn memmove32(dst: *mut u8, src: *u8, size: u32); /// Equivalent to the `llvm.memmove.p0i8.0i8.i64` intrinsic. + #[cfg(stage0)] pub fn memmove64(dst: *mut u8, src: *u8, size: u64); + /// Equivalent to the `llvm.memmove.p0i8.0i8.i32` intrinsic, with a size of + /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()` + #[cfg(not(stage0))] + pub fn memmove32<T>(dst: *mut T, src: *T, count: u32); + /// Equivalent to the `llvm.memmove.p0i8.0i8.i64` intrinsic, with a size of + /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()` + #[cfg(not(stage0))] + pub fn memmove64<T>(dst: *mut T, src: *T, count: u64); + pub fn sqrtf32(x: f32) -> f32; pub fn sqrtf64(x: f64) -> f64; |
