diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2013-05-24 18:05:27 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2013-05-26 10:26:03 -0400 |
| commit | d9c0f0f188eb93fab1077d02de200bc4b961690f (patch) | |
| tree | bb4a1bf091b3be377ae5672d74422e69d790111b | |
| parent | 2eaa5dbb6033a19ab03d40d01e90511b28015d0f (diff) | |
| download | rust-d9c0f0f188eb93fab1077d02de200bc4b961690f.tar.gz rust-d9c0f0f188eb93fab1077d02de200bc4b961690f.zip | |
add memset32/memset64
| -rw-r--r-- | src/librustc/middle/trans/foreign.rs | 26 | ||||
| -rw-r--r-- | src/librustc/middle/trans/type_use.rs | 3 | ||||
| -rw-r--r-- | src/librustc/middle/typeck/check/mod.rs | 24 | ||||
| -rw-r--r-- | src/libstd/ptr.rs | 24 | ||||
| -rw-r--r-- | src/libstd/unstable/intrinsics.rs | 10 |
5 files changed, 86 insertions, 1 deletions
diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 6f420fc44ca..7bfec9c89cb 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -897,6 +897,32 @@ pub fn trans_intrinsic(ccx: @CrateContext, let llfn = *bcx.ccx().intrinsics.get(&~"llvm.memmove.p0i8.p0i8.i64"); Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]); } + ~"memset32" => { + let tp_ty = substs.tys[0]; + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); + + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); + let val = get_param(decl, first_real_arg + 1); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = *bcx.ccx().intrinsics.get(&~"llvm.memset.p0i8.i32"); + Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); + } + ~"memset64" => { + let tp_ty = substs.tys[0]; + let lltp_ty = type_of::type_of(ccx, tp_ty); + let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); + let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); + + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); + let val = get_param(decl, first_real_arg + 1); + let count = get_param(decl, first_real_arg + 2); + let volatile = C_i1(false); + let llfn = *bcx.ccx().intrinsics.get(&~"llvm.memset.p0i8.i64"); + Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]); + } ~"sqrtf32" => { let x = get_param(decl, first_real_arg); let sqrtf = *ccx.intrinsics.get(&~"llvm.sqrt.f32"); diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index a9416a46ddf..ceb229c79bd 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -135,7 +135,8 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint) ~"visit_tydesc" | ~"forget" | ~"frame_address" | ~"morestack_addr" => 0, - ~"memcpy32" | ~"memcpy64" | ~"memmove32" | ~"memmove64" => use_repr, + ~"memcpy32" | ~"memcpy64" | ~"memmove32" | ~"memmove64" | + ~"memset32" | ~"memset64" => use_repr, ~"sqrtf32" | ~"sqrtf64" | ~"powif32" | ~"powif64" | ~"sinf32" | ~"sinf64" | ~"cosf32" | ~"cosf64" | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 1d959a54c0e..d1714555f20 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -3597,6 +3597,30 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { ], ty::mk_nil()) } + ~"memset32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_u8(), + ty::mk_u32() + ], + ty::mk_nil()) + } + ~"memset64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_u8(), + ty::mk_u64() + ], + ty::mk_nil()) + } ~"sqrtf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), ~"sqrtf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), ~"powif32" => { diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 97a7d0e11a6..e787558c6e4 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -19,6 +19,7 @@ use sys; #[cfg(not(test))] use cmp::{Eq, Ord}; use uint; +#[cfg(stage0)] pub mod libc_ { use libc::c_void; use libc; @@ -157,11 +158,26 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u } #[inline(always)] +#[cfg(stage0)] pub unsafe fn set_memory<T>(dst: *mut T, c: int, count: uint) { let n = count * sys::size_of::<T>(); libc_::memset(dst as *mut c_void, c as libc::c_int, n as size_t); } +#[inline(always)] +#[cfg(target_word_size = "32", not(stage0))] +pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) { + use unstable::intrinsics::memset32; + memset32(dst, c, count as u32); +} + +#[inline(always)] +#[cfg(target_word_size = "64", not(stage0))] +pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) { + use unstable::intrinsics::memset64; + memset64(dst, c, count as u64); +} + /** Transform a region pointer - &T - to an unsafe pointer - *T. This is safe, but is implemented with an unsafe block due to @@ -603,4 +619,12 @@ pub mod ptr_tests { }); } } + + #[test] + fn test_set_memory() { + let mut xs = [0u8, ..20]; + let ptr = vec::raw::to_mut_ptr(xs); + unsafe { set_memory(ptr, 5u8, xs.len()); } + assert_eq!(xs, [5u8, ..20]); + } } diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 1aeec0e0b1c..908c5e23ab0 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -31,6 +31,7 @@ A quick refresher on memory ordering: with atomic types and is equivalent to Java's `volatile`. */ + #[abi = "rust-intrinsic"] pub extern "rust-intrinsic" { @@ -152,6 +153,15 @@ pub extern "rust-intrinsic" { #[cfg(not(stage0))] pub fn memmove64<T>(dst: *mut T, src: *T, count: u64); + /// Equivalent to the `llvm.memset.p0i8.i32` intrinsic, with a size of + /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()` + #[cfg(not(stage0))] + pub fn memset32<T>(dst: *mut T, val: u8, count: u32); + /// Equivalent to the `llvm.memset.p0i8.i64` intrinsic, with a size of + /// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()` + #[cfg(not(stage0))] + pub fn memset64<T>(dst: *mut T, val: u8, count: u64); + pub fn sqrtf32(x: f32) -> f32; pub fn sqrtf64(x: f64) -> f64; |
