Skip to content

Commit 556088c

Browse files
committed
auto merge of #10251 : thestinger/rust/ptr, r=alexcritchton
This moves the per-architecture difference into the compiler.
2 parents 29359d0 + 67966fa commit 556088c

File tree

5 files changed

+89
-83
lines changed

5 files changed

+89
-83
lines changed

src/librustc/middle/trans/intrinsic.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,24 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
7474
}
7575
}
7676

77-
fn memcpy_intrinsic(bcx: @mut Block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
77+
fn copy_intrinsic(bcx: @mut Block, allow_overlap: bool, tp_ty: ty::t) {
7878
let ccx = bcx.ccx();
7979
let lltp_ty = type_of::type_of(ccx, tp_ty);
8080
let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
81-
let size = match sizebits {
82-
32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32),
83-
64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64),
84-
_ => ccx.sess.fatal("Invalid value for sizebits")
81+
let size = machine::llsize_of(ccx, lltp_ty);
82+
let int_size = machine::llbitsize_of_real(ccx, ccx.int_type);
83+
let name = if allow_overlap {
84+
if int_size == 32 {
85+
"llvm.memmove.p0i8.p0i8.i32"
86+
} else {
87+
"llvm.memmove.p0i8.p0i8.i64"
88+
}
89+
} else {
90+
if int_size == 32 {
91+
"llvm.memcpy.p0i8.p0i8.i32"
92+
} else {
93+
"llvm.memcpy.p0i8.p0i8.i64"
94+
}
8595
};
8696

8797
let decl = bcx.fcx.llfn;
@@ -95,14 +105,15 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
95105
RetVoid(bcx);
96106
}
97107

98-
fn memset_intrinsic(bcx: @mut Block, name: &'static str, tp_ty: ty::t, sizebits: u8) {
108+
fn memset_intrinsic(bcx: @mut Block, tp_ty: ty::t) {
99109
let ccx = bcx.ccx();
100110
let lltp_ty = type_of::type_of(ccx, tp_ty);
101111
let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32);
102-
let size = match sizebits {
103-
32 => C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32),
104-
64 => C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64),
105-
_ => ccx.sess.fatal("Invalid value for sizebits")
112+
let size = machine::llsize_of(ccx, lltp_ty);
113+
let name = if machine::llbitsize_of_real(ccx, ccx.int_type) == 32 {
114+
"llvm.memset.p0i8.i32"
115+
} else {
116+
"llvm.memset.p0i8.i64"
106117
};
107118

108119
let decl = bcx.fcx.llfn;
@@ -399,12 +410,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
399410
let lladdr = InBoundsGEP(bcx, ptr, [offset]);
400411
Ret(bcx, lladdr);
401412
}
402-
"memcpy32" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i32", substs.tys[0], 32),
403-
"memcpy64" => memcpy_intrinsic(bcx, "llvm.memcpy.p0i8.p0i8.i64", substs.tys[0], 64),
404-
"memmove32" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i32", substs.tys[0], 32),
405-
"memmove64" => memcpy_intrinsic(bcx, "llvm.memmove.p0i8.p0i8.i64", substs.tys[0], 64),
406-
"memset32" => memset_intrinsic(bcx, "llvm.memset.p0i8.i32", substs.tys[0], 32),
407-
"memset64" => memset_intrinsic(bcx, "llvm.memset.p0i8.i64", substs.tys[0], 64),
413+
"copy_nonoverlapping_memory" => copy_intrinsic(bcx, false, substs.tys[0]),
414+
"copy_memory" => copy_intrinsic(bcx, true, substs.tys[0]),
415+
"set_memory" => memset_intrinsic(bcx, substs.tys[0]),
408416
"sqrtf32" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f32", 1),
409417
"sqrtf64" => simple_llvm_intrinsic(bcx, "llvm.sqrt.f64", 1),
410418
"powif32" => simple_llvm_intrinsic(bcx, "llvm.powi.f32", 2),

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

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3734,7 +3734,7 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
37343734
mutbl: ast::MutImmutable
37353735
}))
37363736
}
3737-
"memcpy32" => {
3737+
"copy_nonoverlapping_memory" => {
37383738
(1,
37393739
~[
37403740
ty::mk_ptr(tcx, ty::mt {
@@ -3745,11 +3745,11 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
37453745
ty: param(ccx, 0),
37463746
mutbl: ast::MutImmutable
37473747
}),
3748-
ty::mk_u32()
3748+
ty::mk_uint()
37493749
],
37503750
ty::mk_nil())
37513751
}
3752-
"memcpy64" => {
3752+
"copy_memory" => {
37533753
(1,
37543754
~[
37553755
ty::mk_ptr(tcx, ty::mt {
@@ -3760,61 +3760,19 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) {
37603760
ty: param(ccx, 0),
37613761
mutbl: ast::MutImmutable
37623762
}),
3763-
ty::mk_u64()
3763+
ty::mk_uint()
37643764
],
37653765
ty::mk_nil())
37663766
}
3767-
"memmove32" => {
3768-
(1,
3769-
~[
3770-
ty::mk_ptr(tcx, ty::mt {
3771-
ty: param(ccx, 0),
3772-
mutbl: ast::MutMutable
3773-
}),
3774-
ty::mk_ptr(tcx, ty::mt {
3775-
ty: param(ccx, 0),
3776-
mutbl: ast::MutImmutable
3777-
}),
3778-
ty::mk_u32()
3779-
],
3780-
ty::mk_nil())
3781-
}
3782-
"memmove64" => {
3783-
(1,
3784-
~[
3785-
ty::mk_ptr(tcx, ty::mt {
3786-
ty: param(ccx, 0),
3787-
mutbl: ast::MutMutable
3788-
}),
3789-
ty::mk_ptr(tcx, ty::mt {
3790-
ty: param(ccx, 0),
3791-
mutbl: ast::MutImmutable
3792-
}),
3793-
ty::mk_u64()
3794-
],
3795-
ty::mk_nil())
3796-
}
3797-
"memset32" => {
3798-
(1,
3799-
~[
3800-
ty::mk_ptr(tcx, ty::mt {
3801-
ty: param(ccx, 0),
3802-
mutbl: ast::MutMutable
3803-
}),
3804-
ty::mk_u8(),
3805-
ty::mk_u32()
3806-
],
3807-
ty::mk_nil())
3808-
}
3809-
"memset64" => {
3767+
"set_memory" => {
38103768
(1,
38113769
~[
38123770
ty::mk_ptr(tcx, ty::mt {
38133771
ty: param(ccx, 0),
38143772
mutbl: ast::MutMutable
38153773
}),
38163774
ty::mk_u8(),
3817-
ty::mk_u64()
3775+
ty::mk_uint()
38183776
],
38193777
ty::mk_nil())
38203778
}

src/libstd/cast.rs

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,15 @@
1313
use ptr::RawPtr;
1414
use mem;
1515
use unstable::intrinsics;
16+
use ptr::copy_nonoverlapping_memory;
1617

1718
/// Casts the value at `src` to U. The two types must have the same length.
18-
#[cfg(target_word_size = "32")]
1919
#[inline]
2020
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
2121
let mut dest: U = intrinsics::uninit();
2222
let dest_ptr: *mut u8 = transmute(&mut dest);
2323
let src_ptr: *u8 = transmute(src);
24-
intrinsics::memcpy32(dest_ptr, src_ptr, mem::size_of::<U>() as u32);
25-
dest
26-
}
27-
28-
/// Casts the value at `src` to U. The two types must have the same length.
29-
#[cfg(target_word_size = "64")]
30-
#[inline]
31-
pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
32-
let mut dest: U = intrinsics::uninit();
33-
let dest_ptr: *mut u8 = transmute(&mut dest);
34-
let src_ptr: *u8 = transmute(src);
35-
intrinsics::memcpy64(dest_ptr, src_ptr, mem::size_of::<U>() as u64);
24+
copy_nonoverlapping_memory(dest_ptr, src_ptr, mem::size_of::<U>());
3625
dest
3726
}
3827

src/libstd/ptr.rs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub fn is_not_null<T,P:RawPtr<T>>(ptr: P) -> bool { ptr.is_not_null() }
8787
* and destination may overlap.
8888
*/
8989
#[inline]
90-
#[cfg(target_word_size = "32")]
90+
#[cfg(target_word_size = "32", stage0)]
9191
pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
9292
intrinsics::memmove32(dst,
9393
cast::transmute_immut_unsafe(src),
@@ -101,21 +101,33 @@ pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
101101
* and destination may overlap.
102102
*/
103103
#[inline]
104-
#[cfg(target_word_size = "64")]
104+
#[cfg(target_word_size = "64", stage0)]
105105
pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
106106
intrinsics::memmove64(dst,
107107
cast::transmute_immut_unsafe(src),
108108
count as u64);
109109
}
110110

111+
/**
112+
* Copies data from one location to another.
113+
*
114+
* Copies `count` elements (not bytes) from `src` to `dst`. The source
115+
* and destination may overlap.
116+
*/
117+
#[inline]
118+
#[cfg(not(stage0))]
119+
pub unsafe fn copy_memory<T,P:RawPtr<T>>(dst: *mut T, src: P, count: uint) {
120+
intrinsics::copy_memory(dst, cast::transmute_immut_unsafe(src), count)
121+
}
122+
111123
/**
112124
* Copies data from one location to another.
113125
*
114126
* Copies `count` elements (not bytes) from `src` to `dst`. The source
115127
* and destination may *not* overlap.
116128
*/
117129
#[inline]
118-
#[cfg(target_word_size = "32")]
130+
#[cfg(target_word_size = "32", stage0)]
119131
pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
120132
src: P,
121133
count: uint) {
@@ -131,7 +143,7 @@ pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
131143
* and destination may *not* overlap.
132144
*/
133145
#[inline]
134-
#[cfg(target_word_size = "64")]
146+
#[cfg(target_word_size = "64", stage0)]
135147
pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
136148
src: P,
137149
count: uint) {
@@ -140,12 +152,26 @@ pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
140152
count as u64);
141153
}
142154

155+
/**
156+
* Copies data from one location to another.
157+
*
158+
* Copies `count` elements (not bytes) from `src` to `dst`. The source
159+
* and destination may *not* overlap.
160+
*/
161+
#[inline]
162+
#[cfg(not(stage0))]
163+
pub unsafe fn copy_nonoverlapping_memory<T,P:RawPtr<T>>(dst: *mut T,
164+
src: P,
165+
count: uint) {
166+
intrinsics::copy_nonoverlapping_memory(dst, cast::transmute_immut_unsafe(src), count)
167+
}
168+
143169
/**
144170
* Invokes memset on the specified pointer, setting `count * size_of::<T>()`
145171
* bytes of memory starting at `dst` to `c`.
146172
*/
147173
#[inline]
148-
#[cfg(target_word_size = "32")]
174+
#[cfg(target_word_size = "32", stage0)]
149175
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
150176
intrinsics::memset32(dst, c, count as u32);
151177
}
@@ -155,11 +181,21 @@ pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
155181
* bytes of memory starting at `dst` to `c`.
156182
*/
157183
#[inline]
158-
#[cfg(target_word_size = "64")]
184+
#[cfg(target_word_size = "64", stage0)]
159185
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
160186
intrinsics::memset64(dst, c, count as u64);
161187
}
162188

189+
/**
190+
* Invokes memset on the specified pointer, setting `count * size_of::<T>()`
191+
* bytes of memory starting at `dst` to `c`.
192+
*/
193+
#[inline]
194+
#[cfg(not(stage0))]
195+
pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
196+
intrinsics::set_memory(dst, c, count)
197+
}
198+
163199
/**
164200
* Zeroes out `count * size_of::<T>` bytes of memory at `dst`
165201
*/

src/libstd/unstable/intrinsics.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,25 +345,40 @@ extern "rust-intrinsic" {
345345

346346
/// Equivalent to the `llvm.memcpy.p0i8.0i8.i32` intrinsic, with a size of
347347
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
348+
#[cfg(stage0)]
348349
pub fn memcpy32<T>(dst: *mut T, src: *T, count: u32);
349350
/// Equivalent to the `llvm.memcpy.p0i8.0i8.i64` intrinsic, with a size of
350351
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
352+
#[cfg(stage0)]
351353
pub fn memcpy64<T>(dst: *mut T, src: *T, count: u64);
352354

353355
/// Equivalent to the `llvm.memmove.p0i8.0i8.i32` intrinsic, with a size of
354356
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
357+
#[cfg(stage0)]
355358
pub fn memmove32<T>(dst: *mut T, src: *T, count: u32);
356359
/// Equivalent to the `llvm.memmove.p0i8.0i8.i64` intrinsic, with a size of
357360
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
361+
#[cfg(stage0)]
358362
pub fn memmove64<T>(dst: *mut T, src: *T, count: u64);
359363

360364
/// Equivalent to the `llvm.memset.p0i8.i32` intrinsic, with a size of
361365
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
366+
#[cfg(stage0)]
362367
pub fn memset32<T>(dst: *mut T, val: u8, count: u32);
363368
/// Equivalent to the `llvm.memset.p0i8.i64` intrinsic, with a size of
364369
/// `count` * `size_of::<T>()` and an alignment of `min_align_of::<T>()`
370+
#[cfg(stage0)]
365371
pub fn memset64<T>(dst: *mut T, val: u8, count: u64);
366372

373+
#[cfg(not(stage0))]
374+
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *T, count: uint);
375+
376+
#[cfg(not(stage0))]
377+
pub fn copy_memory<T>(dst: *mut T, src: *T, count: uint);
378+
379+
#[cfg(not(stage0))]
380+
pub fn set_memory<T>(dst: *mut T, val: u8, count: uint);
381+
367382
pub fn sqrtf32(x: f32) -> f32;
368383
pub fn sqrtf64(x: f64) -> f64;
369384

0 commit comments

Comments
 (0)