@@ -51,7 +51,8 @@ type glue_fns = rec(ValueRef activate_glue,
51
51
ValueRef yield_glue ,
52
52
ValueRef exit_task_glue ,
53
53
vec[ ValueRef ] upcall_glues ,
54
- ValueRef no_op_type_glue ) ;
54
+ ValueRef no_op_type_glue ,
55
+ ValueRef memcpy_glue ) ;
55
56
56
57
tag arity { nullary; n_ary; }
57
58
type tag_info = rec ( type_handle th,
@@ -1237,26 +1238,15 @@ fn drop_ty(@block_ctxt cx,
1237
1238
ret res( cx, C_nil ( ) ) ;
1238
1239
}
1239
1240
1240
- fn build_memcpy( @block_ctxt cx,
1241
- ValueRef dst,
1242
- ValueRef src,
1243
- ValueRef n_bytes) -> result {
1244
- // FIXME: switch to the 64-bit variant when on such a platform.
1245
- check ( cx. fcx. ccx. intrinsics. contains_key( "llvm.memcpy.p0i8.p0i8.i32" ) ) ;
1246
- auto memcpy = cx. fcx. ccx. intrinsics. get( "llvm.memcpy.p0i8.p0i8.i32" ) ;
1241
+ fn call_memcpy( @block_ctxt cx,
1242
+ ValueRef dst,
1243
+ ValueRef src,
1244
+ ValueRef n_bytes) -> result {
1247
1245
auto src_ptr = cx. build. PointerCast ( src, T_ptr( T_i8 ( ) ) ) ;
1248
1246
auto dst_ptr = cx. build. PointerCast ( dst, T_ptr ( T_i8 ( ) ) ) ;
1249
- auto size = cx. build. IntCast ( n_bytes, T_i32 ( ) ) ;
1250
- auto align = cx. build. IntCast ( C_int ( 1 ) , T_i32 ( ) ) ;
1251
-
1252
- // FIXME: align seems like it should be
1253
- // lib.llvm.llvm.LLVMAlignOf(llty);
1254
- // but this makes it upset because it's not a constant.
1255
-
1256
- auto volatile = C_integral ( 0 , T_i1 ( ) ) ;
1257
- ret res( cx, cx. build. Call ( memcpy,
1258
- vec( dst_ptr, src_ptr,
1259
- size, align, volatile) ) ) ;
1247
+ auto size = cx. build. IntCast ( n_bytes, T_int ( ) ) ;
1248
+ ret res( cx, cx. build. FastCall ( cx. fcx. ccx. glues. memcpy_glue,
1249
+ vec( dst_ptr, src_ptr, size) ) ) ;
1260
1250
}
1261
1251
1262
1252
fn memcpy_ty( @block_ctxt cx,
@@ -1266,7 +1256,7 @@ fn memcpy_ty(@block_ctxt cx,
1266
1256
if ( ty. type_has_dynamic_size( t) ) {
1267
1257
auto llszptr = field_of_tydesc( cx, t, abi. tydesc_field_size) ;
1268
1258
auto llsz = cx. build. Load ( llszptr) ;
1269
- ret build_memcpy ( cx, dst, src, llsz) ;
1259
+ ret call_memcpy ( cx, dst, src, llsz) ;
1270
1260
1271
1261
} else {
1272
1262
ret res( cx, cx. build. Store ( cx. build. Load ( src) , dst) ) ;
@@ -3624,21 +3614,11 @@ fn trans_main_fn(@crate_ctxt cx, ValueRef llcrate) {
3624
3614
fn declare_intrinsics ( ModuleRef llmod) -> hashmap [ str, ValueRef ] {
3625
3615
3626
3616
let vec[ TypeRef ] T_trap_args = vec ( ) ;
3627
- let vec[ TypeRef ] T_memcpy32_args = vec ( T_ptr ( T_i8 ( ) ) , T_ptr ( T_i8 ( ) ) ,
3628
- T_i32 ( ) , T_i32 ( ) , T_i1 ( ) ) ;
3629
- let vec[ TypeRef ] T_memcpy64_args = vec ( T_ptr ( T_i8 ( ) ) , T_ptr ( T_i8 ( ) ) ,
3630
- T_i32 ( ) , T_i32 ( ) , T_i1 ( ) ) ;
3631
3617
auto trap = decl_cdecl_fn ( llmod, "llvm.trap" ,
3632
3618
T_fn ( T_trap_args , T_void ( ) ) ) ;
3633
- auto memcpy32 = decl_cdecl_fn ( llmod, "llvm.memcpy.p0i8.p0i8.i32" ,
3634
- T_fn ( T_memcpy32_args , T_void ( ) ) ) ;
3635
- auto memcpy64 = decl_cdecl_fn ( llmod, "llvm.memcpy.p0i8.p0i8.i64" ,
3636
- T_fn ( T_memcpy64_args , T_void ( ) ) ) ;
3637
3619
3638
3620
auto intrinsics = new_str_hash[ ValueRef ] ( ) ;
3639
3621
intrinsics. insert ( "llvm.trap" , trap) ;
3640
- intrinsics. insert ( "llvm.memcpy.p0i8.p0i8.i32" , memcpy32) ;
3641
- intrinsics. insert ( "llvm.memcpy.p0i8.p0i8.i64" , memcpy64) ;
3642
3622
ret intrinsics;
3643
3623
}
3644
3624
@@ -3652,13 +3632,58 @@ fn check_module(ModuleRef llmod) {
3652
3632
3653
3633
fn make_no_op_type_glue ( ModuleRef llmod) -> ValueRef {
3654
3634
auto ty = T_fn ( vec ( T_taskptr ( ) , T_ptr ( T_i8 ( ) ) ) , T_void ( ) ) ;
3655
- auto fun = decl_fastcall_fn ( llmod, "_rust_no_op_type_glue" , ty) ;
3635
+ auto fun = decl_fastcall_fn ( llmod, abi . no_op_type_glue_name ( ) , ty) ;
3656
3636
auto bb_name = _str. buf ( "_rust_no_op_type_glue_bb" ) ;
3657
3637
auto llbb = llvm. LLVMAppendBasicBlock ( fun, bb_name) ;
3658
3638
new_builder ( llbb) . RetVoid ( ) ;
3659
3639
ret fun;
3660
3640
}
3661
3641
3642
+ fn make_memcpy_glue ( ModuleRef llmod) -> ValueRef {
3643
+
3644
+ // We're not using the LLVM memcpy intrinsic. It appears to call through
3645
+ // to the platform memcpy in some cases, which is not terribly safe to run
3646
+ // on a rust stack.
3647
+
3648
+ auto p8 = T_ptr ( T_i8 ( ) ) ;
3649
+
3650
+ auto ty = T_fn ( vec ( p8, p8, T_int ( ) ) , T_void ( ) ) ;
3651
+ auto fun = decl_fastcall_fn ( llmod, abi. memcpy_glue_name ( ) , ty) ;
3652
+
3653
+ auto initbb = llvm. LLVMAppendBasicBlock ( fun, _str. buf ( "init" ) ) ;
3654
+ auto hdrbb = llvm. LLVMAppendBasicBlock ( fun, _str. buf ( "hdr" ) ) ;
3655
+ auto loopbb = llvm. LLVMAppendBasicBlock ( fun, _str. buf ( "loop" ) ) ;
3656
+ auto endbb = llvm. LLVMAppendBasicBlock ( fun, _str. buf ( "end" ) ) ;
3657
+
3658
+ auto dst = llvm. LLVMGetParam ( fun, 0 u) ;
3659
+ auto src = llvm. LLVMGetParam ( fun, 1 u) ;
3660
+ auto count = llvm. LLVMGetParam ( fun, 2 u) ;
3661
+
3662
+ // Init block.
3663
+ auto ib = new_builder ( initbb) ;
3664
+ auto ip = ib. Alloca ( T_int ( ) ) ;
3665
+ ib. Store ( C_int ( 0 ) , ip) ;
3666
+ ib. Br ( hdrbb) ;
3667
+
3668
+ // Loop-header block
3669
+ auto hb = new_builder ( hdrbb) ;
3670
+ auto i = hb. Load ( ip) ;
3671
+ hb. CondBr ( hb. ICmp ( lib. llvm . LLVMIntEQ , count, i) , endbb, loopbb) ;
3672
+
3673
+ // Loop-body block
3674
+ auto lb = new_builder ( loopbb) ;
3675
+ i = lb. Load ( ip) ;
3676
+ lb. Store ( lb. Load ( lb. GEP ( src, vec ( i) ) ) ,
3677
+ lb. GEP ( dst, vec ( i) ) ) ;
3678
+ lb. Store ( lb. Add ( i, C_int ( 1 ) ) , ip) ;
3679
+ lb. Br ( hdrbb) ;
3680
+
3681
+ // End block
3682
+ auto eb = new_builder ( endbb) ;
3683
+ eb. RetVoid ( ) ;
3684
+ ret fun;
3685
+ }
3686
+
3662
3687
fn make_glues ( ModuleRef llmod) -> @glue_fns {
3663
3688
ret @rec( activate_glue = decl_glue ( llmod, abi. activate_glue_name ( ) ) ,
3664
3689
yield_glue = decl_glue ( llmod, abi. yield_glue_name ( ) ) ,
@@ -3678,7 +3703,8 @@ fn make_glues(ModuleRef llmod) -> @glue_fns {
3678
3703
upcall_glues =
3679
3704
_vec. init_fn [ ValueRef ] ( bind decl_upcall ( llmod, _) ,
3680
3705
abi. n_upcall_glues as uint ) ,
3681
- no_op_type_glue = make_no_op_type_glue ( llmod) ) ;
3706
+ no_op_type_glue = make_no_op_type_glue ( llmod) ,
3707
+ memcpy_glue = make_memcpy_glue ( llmod) ) ;
3682
3708
}
3683
3709
3684
3710
fn trans_crate ( session . session sess, @ast. crate crate, str output ,
0 commit comments