Skip to content

Commit d9c0f0f

Browse files
committed
add memset32/memset64
1 parent 2eaa5db commit d9c0f0f

File tree

5 files changed

+86
-1
lines changed

5 files changed

+86
-1
lines changed

src/librustc/middle/trans/foreign.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,32 @@ pub fn trans_intrinsic(ccx: @CrateContext,
897897
let llfn = *bcx.ccx().intrinsics.get(&~"llvm.memmove.p0i8.p0i8.i64");
898898
Call(bcx, llfn, [dst_ptr, src_ptr, Mul(bcx, size, count), align, volatile]);
899899
}
900+
~"memset32" => {
901+
let tp_ty = substs.tys[0];
902+
let lltp_ty = type_of::type_of(ccx, tp_ty);
903+
let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
904+
let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32);
905+
906+
let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8()));
907+
let val = get_param(decl, first_real_arg + 1);
908+
let count = get_param(decl, first_real_arg + 2);
909+
let volatile = C_i1(false);
910+
let llfn = *bcx.ccx().intrinsics.get(&~"llvm.memset.p0i8.i32");
911+
Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]);
912+
}
913+
~"memset64" => {
914+
let tp_ty = substs.tys[0];
915+
let lltp_ty = type_of::type_of(ccx, tp_ty);
916+
let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
917+
let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64);
918+
919+
let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8()));
920+
let val = get_param(decl, first_real_arg + 1);
921+
let count = get_param(decl, first_real_arg + 2);
922+
let volatile = C_i1(false);
923+
let llfn = *bcx.ccx().intrinsics.get(&~"llvm.memset.p0i8.i64");
924+
Call(bcx, llfn, [dst_ptr, val, Mul(bcx, size, count), align, volatile]);
925+
}
900926
~"sqrtf32" => {
901927
let x = get_param(decl, first_real_arg);
902928
let sqrtf = *ccx.intrinsics.get(&~"llvm.sqrt.f32");

src/librustc/middle/trans/type_use.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ pub fn type_uses_for(ccx: @CrateContext, fn_id: def_id, n_tps: uint)
135135
~"visit_tydesc" | ~"forget" | ~"frame_address" |
136136
~"morestack_addr" => 0,
137137

138-
~"memcpy32" | ~"memcpy64" | ~"memmove32" | ~"memmove64" => use_repr,
138+
~"memcpy32" | ~"memcpy64" | ~"memmove32" | ~"memmove64" |
139+
~"memset32" | ~"memset64" => use_repr,
139140

140141
~"sqrtf32" | ~"sqrtf64" | ~"powif32" | ~"powif64" |
141142
~"sinf32" | ~"sinf64" | ~"cosf32" | ~"cosf64" |

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3597,6 +3597,30 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
35973597
],
35983598
ty::mk_nil())
35993599
}
3600+
~"memset32" => {
3601+
(1,
3602+
~[
3603+
ty::mk_ptr(tcx, ty::mt {
3604+
ty: param(ccx, 0),
3605+
mutbl: ast::m_mutbl
3606+
}),
3607+
ty::mk_u8(),
3608+
ty::mk_u32()
3609+
],
3610+
ty::mk_nil())
3611+
}
3612+
~"memset64" => {
3613+
(1,
3614+
~[
3615+
ty::mk_ptr(tcx, ty::mt {
3616+
ty: param(ccx, 0),
3617+
mutbl: ast::m_mutbl
3618+
}),
3619+
ty::mk_u8(),
3620+
ty::mk_u64()
3621+
],
3622+
ty::mk_nil())
3623+
}
36003624
~"sqrtf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()),
36013625
~"sqrtf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()),
36023626
~"powif32" => {

src/libstd/ptr.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use sys;
1919
#[cfg(not(test))] use cmp::{Eq, Ord};
2020
use uint;
2121

22+
#[cfg(stage0)]
2223
pub mod libc_ {
2324
use libc::c_void;
2425
use libc;
@@ -157,11 +158,26 @@ pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: u
157158
}
158159

159160
#[inline(always)]
161+
#[cfg(stage0)]
160162
pub unsafe fn set_memory<T>(dst: *mut T, c: int, count: uint) {
161163
let n = count * sys::size_of::<T>();
162164
libc_::memset(dst as *mut c_void, c as libc::c_int, n as size_t);
163165
}
164166

167+
#[inline(always)]
168+
#[cfg(target_word_size = "32", not(stage0))]
169+
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
170+
use unstable::intrinsics::memset32;
171+
memset32(dst, c, count as u32);
172+
}
173+
174+
#[inline(always)]
175+
#[cfg(target_word_size = "64", not(stage0))]
176+
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
177+
use unstable::intrinsics::memset64;
178+
memset64(dst, c, count as u64);
179+
}
180+
165181
/**
166182
Transform a region pointer - &T - to an unsafe pointer - *T.
167183
This is safe, but is implemented with an unsafe block due to
@@ -603,4 +619,12 @@ pub mod ptr_tests {
603619
});
604620
}
605621
}
622+
623+
#[test]
624+
fn test_set_memory() {
625+
let mut xs = [0u8, ..20];
626+
let ptr = vec::raw::to_mut_ptr(xs);
627+
unsafe { set_memory(ptr, 5u8, xs.len()); }
628+
assert_eq!(xs, [5u8, ..20]);
629+
}
606630
}

src/libstd/unstable/intrinsics.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ A quick refresher on memory ordering:
3131
with atomic types and is equivalent to Java's `volatile`.
3232
3333
*/
34+
3435
#[abi = "rust-intrinsic"]
3536
pub extern "rust-intrinsic" {
3637

@@ -152,6 +153,15 @@ pub extern "rust-intrinsic" {
152153
#[cfg(not(stage0))]
153154
pub fn memmove64<T>(dst: *mut T, src: *T, count: u64);
154155

156+
/// Equivalent to the `llvm.memset.p0i8.i32` intrinsic, with a size of
157+
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
158+
#[cfg(not(stage0))]
159+
pub fn memset32<T>(dst: *mut T, val: u8, count: u32);
160+
/// Equivalent to the `llvm.memset.p0i8.i64` intrinsic, with a size of
161+
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
162+
#[cfg(not(stage0))]
163+
pub fn memset64<T>(dst: *mut T, val: u8, count: u64);
164+
155165
pub fn sqrtf32(x: f32) -> f32;
156166
pub fn sqrtf64(x: f64) -> f64;
157167

0 commit comments

Comments
 (0)