@@ -64,6 +64,7 @@ let mk_load_atomic memory_chunk =
64
64
65
65
let floatarray_tag dbg = Cconst_int (Obj. double_array_tag, dbg)
66
66
67
+ (* CR mshinwell: update to use NOT_MARKABLE terminology *)
67
68
let block_header tag sz =
68
69
Nativeint. add
69
70
(Nativeint. shift_left (Nativeint. of_int sz) 10 )
@@ -118,6 +119,8 @@ let boxedint64_local_header =
118
119
119
120
let boxedintnat_local_header = local_block_header Obj. custom_tag 2
120
121
122
+ let black_custom_header ~size = black_block_header Obj. custom_tag size
123
+
121
124
let custom_header ~size = block_header Obj. custom_tag size
122
125
123
126
let custom_local_header ~size = local_block_header Obj. custom_tag size
@@ -924,7 +927,6 @@ let unboxed_int32_array_length arr dbg =
924
927
sub_int (get_size arr dbg) (int ~dbg 1 ) dbg,
925
928
Clet
926
929
( VP. create custom_ops_var,
927
- (* CR gbury/mshinwell: check the atomicity of this load *)
928
930
Cop (mk_load_immut Word_int , [arr], dbg),
929
931
Cifthenelse
930
932
( Cop
@@ -1024,6 +1026,36 @@ let addr_array_initialize arr ofs newval dbg =
1024
1026
[array_indexing log2_size_addr arr ofs dbg; newval],
1025
1027
dbg )
1026
1028
1029
+ (* low_32 x is a value which agrees with x on at least the low 32 bits *)
1030
+ let rec low_32 dbg = function
1031
+ (* Ignore sign and zero extensions, which do not affect the low bits *)
1032
+ | Cop (Casr , [Cop (Clsl , [x; Cconst_int (32 , _)], _); Cconst_int (32 , _)], _)
1033
+ | Cop (Cand, [x ; Cconst_natint (0xFFFFFFFFn , _ )], _ ) ->
1034
+ low_32 dbg x
1035
+ | Clet (id , e , body ) -> Clet (id, e, low_32 dbg body)
1036
+ | x -> x
1037
+
1038
+ (* sign_extend_32 sign-extends values from 32 bits to the word size. *)
1039
+ let sign_extend_32 dbg e =
1040
+ match low_32 dbg e with
1041
+ | Cop
1042
+ ( Cload
1043
+ { memory_chunk = Thirtytwo_unsigned | Thirtytwo_signed ;
1044
+ mutability;
1045
+ is_atomic
1046
+ },
1047
+ args,
1048
+ dbg ) ->
1049
+ Cop
1050
+ ( Cload { memory_chunk = Thirtytwo_signed ; mutability; is_atomic },
1051
+ args,
1052
+ dbg )
1053
+ | e ->
1054
+ Cop
1055
+ ( Casr ,
1056
+ [Cop (Clsl , [e; Cconst_int (32 , dbg)], dbg); Cconst_int (32 , dbg)],
1057
+ dbg )
1058
+
1027
1059
let unboxed_int32_array_ref arr index dbg =
1028
1060
bind " arr" arr (fun arr ->
1029
1061
bind " index" index (fun index ->
@@ -1034,11 +1066,12 @@ let unboxed_int32_array_ref arr index dbg =
1034
1066
add_int index (int ~dbg 2 ) dbg
1035
1067
in
1036
1068
let log2_size_addr = 2 in
1037
- Cop
1038
- (* CR gbury/mshinwell: check the atomicity of the load *)
1039
- ( mk_load_mut Thirtytwo_signed ,
1040
- [array_indexing log2_size_addr arr index dbg],
1041
- dbg )))
1069
+ (* N.B. The resulting value must be sign extended! *)
1070
+ sign_extend_32 dbg
1071
+ (Cop
1072
+ ( mk_load_mut Thirtytwo_signed ,
1073
+ [array_indexing log2_size_addr arr index dbg],
1074
+ dbg ))))
1042
1075
1043
1076
let unboxed_int64_or_nativeint_array_ref arr index dbg =
1044
1077
bind " arr" arr (fun arr ->
@@ -1416,15 +1449,6 @@ let check_64_bit_target func =
1416
1449
Misc. fatal_errorf
1417
1450
" Cmm helpers function %s can only be used on 64-bit targets" func
1418
1451
1419
- (* low_32 x is a value which agrees with x on at least the low 32 bits *)
1420
- let rec low_32 dbg = function
1421
- (* Ignore sign and zero extensions, which do not affect the low bits *)
1422
- | Cop (Casr , [Cop (Clsl , [x; Cconst_int (32 , _)], _); Cconst_int (32 , _)], _)
1423
- | Cop (Cand, [x ; Cconst_natint (0xFFFFFFFFn , _ )], _ ) ->
1424
- low_32 dbg x
1425
- | Clet (id , e , body ) -> Clet (id, e, low_32 dbg body)
1426
- | x -> x
1427
-
1428
1452
(* Like [low_32] but for 63-bit integers held in 64-bit registers. *)
1429
1453
(* CR gbury: Why not use Cmm.map_tail here ? It seems designed for that kind of
1430
1454
thing (and covers more cases than just Clet). *)
@@ -1438,27 +1462,6 @@ let rec low_63 dbg e =
1438
1462
| Clet (id , x , body ) -> Clet (id, x, low_63 dbg body)
1439
1463
| _ -> e
1440
1464
1441
- (* sign_extend_32 sign-extends values from 32 bits to the word size. *)
1442
- let sign_extend_32 dbg e =
1443
- match low_32 dbg e with
1444
- | Cop
1445
- ( Cload
1446
- { memory_chunk = Thirtytwo_unsigned | Thirtytwo_signed ;
1447
- mutability;
1448
- is_atomic
1449
- },
1450
- args,
1451
- dbg ) ->
1452
- Cop
1453
- ( Cload { memory_chunk = Thirtytwo_signed ; mutability; is_atomic },
1454
- args,
1455
- dbg )
1456
- | e ->
1457
- Cop
1458
- ( Casr ,
1459
- [Cop (Clsl , [e; Cconst_int (32 , dbg)], dbg); Cconst_int (32 , dbg)],
1460
- dbg )
1461
-
1462
1465
(* CR-someday mshinwell/gbury: sign_extend_63 then tag_int should simplify to
1463
1466
just tag_int. Similarly, untag_int then sign_extend_63 should simplify to
1464
1467
untag_int. *)
@@ -2860,13 +2863,13 @@ let arraylength kind arg dbg =
2860
2863
in
2861
2864
Cop (Cor , [len; Cconst_int (1 , dbg)], dbg)
2862
2865
| Paddrarray | Pintarray ->
2863
- (* Note we only support 64 bit targets now, so this is ok for
2864
- Punboxedfloatarray *)
2865
2866
Cop (Cor , [addr_array_length_shifted hdr dbg; Cconst_int (1 , dbg)], dbg)
2866
- | Punboxedintarray Pint64 | Punboxedintarray Pnativeint ->
2867
- unboxed_int64_or_nativeint_array_length arg dbg
2868
2867
| Pfloatarray | Punboxedfloatarray ->
2868
+ (* Note: we only support 64 bit targets now, so this is ok for
2869
+ Punboxedfloatarray *)
2869
2870
Cop (Cor , [float_array_length_shifted hdr dbg; Cconst_int (1 , dbg)], dbg)
2871
+ | Punboxedintarray Pint64 | Punboxedintarray Pnativeint ->
2872
+ unboxed_int64_or_nativeint_array_length arg dbg
2870
2873
| Punboxedintarray Pint32 -> unboxed_int32_array_length arg dbg
2871
2874
2872
2875
(* CR-soon gyorsh: effects and coeffects for primitives are set conservatively
@@ -3708,32 +3711,39 @@ let atomic_compare_and_set ~dbg atomic ~old_value ~new_value =
3708
3711
[atomic; old_value; new_value],
3709
3712
dbg )
3710
3713
3714
+ type even_or_odd =
3715
+ | Even
3716
+ | Odd
3717
+
3711
3718
let make_unboxed_int32_array_payload dbg unboxed_int32_list =
3719
+ (* CR mshinwell/gbury: potential big-endian implementations:
3720
+ *
3721
+ * let i =
3722
+ * if big_endian
3723
+ * then Cop (Clsl, [a; Cconst_int (32, dbg)], dbg)
3724
+ * else a
3725
+ * in
3726
+ * ...
3727
+ * let i =
3728
+ * if big_endian
3729
+ * then Cop (Cor, [Cop (Clsl, [a; Cconst_int (32, dbg)], dbg); b], dbg)
3730
+ * else Cop (Cor, [a; Cop (Clsl, [b; Cconst_int (32, dbg)], dbg)], dbg)
3731
+ * in
3732
+ *)
3733
+ if Sys. big_endian
3734
+ then
3735
+ Misc. fatal_error " Big-endian platforms not yet supported for unboxed arrays" ;
3712
3736
let rec aux acc = function
3713
- | [] -> true , List. rev acc
3714
- | a :: [] ->
3715
- let i =
3716
- (* CR gbury: check/test that this is correct *)
3717
- if big_endian
3718
- then Cop (Clsl , [a; Cconst_int (32 , dbg)], dbg)
3719
- else sign_extend_32 dbg a
3720
- in
3721
- false , List. rev (i :: acc)
3737
+ | [] -> Even , List. rev acc
3738
+ | a :: [] -> Odd , List. rev (a :: acc)
3722
3739
| a :: b :: r ->
3723
- let i =
3724
- (* CR gbury: check/test that this is correct *)
3725
- if big_endian
3726
- then Cop (Cor , [Cop (Clsl , [a; Cconst_int (32 , dbg)], dbg); b], dbg)
3727
- else Cop (Cor , [a; Cop (Clsl , [b; Cconst_int (32 , dbg)], dbg)], dbg)
3728
- in
3740
+ let i = Cop (Cor , [a; Cop (Clsl , [b; Cconst_int (32 , dbg)], dbg)], dbg) in
3729
3741
aux (i :: acc) r
3730
3742
in
3731
3743
aux [] unboxed_int32_list
3732
3744
3733
3745
let allocate_unboxed_int32_array ~elements (mode : Lambda.alloc_mode ) dbg =
3734
- let even_num_of_elts, payload =
3735
- make_unboxed_int32_array_payload dbg elements
3736
- in
3746
+ let num_elts, payload = make_unboxed_int32_array_payload dbg elements in
3737
3747
let header =
3738
3748
let size = 1 (* custom_ops field *) + List. length payload in
3739
3749
match mode with
@@ -3742,10 +3752,10 @@ let allocate_unboxed_int32_array ~elements (mode : Lambda.alloc_mode) dbg =
3742
3752
in
3743
3753
let custom_ops =
3744
3754
(* For odd-length unboxed int32 arrays there are 32 bits spare at the end of
3745
- the block *)
3746
- if even_num_of_elts
3747
- then custom_ops_unboxed_int32_even_array
3748
- else custom_ops_unboxed_int32_odd_array
3755
+ the block, which are never read. *)
3756
+ match num_elts with
3757
+ | Even -> custom_ops_unboxed_int32_even_array
3758
+ | Odd -> custom_ops_unboxed_int32_odd_array
3749
3759
in
3750
3760
Cop (Calloc mode, Cconst_natint (header, dbg) :: custom_ops :: payload, dbg)
3751
3761
0 commit comments