about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Micay <danielmicay@gmail.com>2013-05-24 18:05:27 -0400
committerDaniel Micay <danielmicay@gmail.com>2013-05-26 10:26:03 -0400
commitd9c0f0f188eb93fab1077d02de200bc4b961690f (patch)
treebb4a1bf091b3be377ae5672d74422e69d790111b
parent2eaa5dbb6033a19ab03d40d01e90511b28015d0f (diff)
downloadrust-d9c0f0f188eb93fab1077d02de200bc4b961690f.tar.gz
rust-d9c0f0f188eb93fab1077d02de200bc4b961690f.zip
add memset32/memset64
-rw-r--r--src/librustc/middle/trans/foreign.rs26
-rw-r--r--src/librustc/middle/trans/type_use.rs3
-rw-r--r--src/librustc/middle/typeck/check/mod.rs24
-rw-r--r--src/libstd/ptr.rs24
-rw-r--r--src/libstd/unstable/intrinsics.rs10
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;