@@ -20,6 +20,8 @@ module VP = Backend_var.With_provenance
20
20
open Cmm
21
21
open Arch
22
22
23
+ let arch_bits = Arch. size_int * 8
24
+
23
25
type arity =
24
26
{ function_kind : Lambda .function_kind ;
25
27
params_layout : Lambda .layout list ;
@@ -749,35 +751,46 @@ let mod_int c1 c2 is_safe dbg =
749
751
(* Division or modulo on boxed integers. The overflow case min_int / -1 can
750
752
occur, in which case we force x / -1 = -x and x mod -1 = 0. (PR#5513). *)
751
753
752
- let is_different_from x = function
753
- | Cconst_int (n , _ ) -> n <> x
754
- | Cconst_natint (n , _ ) -> n <> Nativeint. of_int x
755
- | _ -> false
754
+ (* Division or modulo on boxed integers. The overflow case min_int / -1 can
755
+ occur, in which case we force x / -1 = -x and x mod -1 = 0. (PR#5513). *)
756
756
757
- let safe_divmod_bi mkop kind is_safe mkm1 c1 c2 bi dbg =
758
- bind " divisor" c2 (fun c2 ->
759
- bind " dividend" c1 (fun c1 ->
760
- let c = mkop c1 c2 is_safe dbg in
761
- if Arch. division_crashes_on_overflow
762
- && bi <> Primitive. Unboxed_int32
763
- && not (is_different_from (- 1 ) c2)
764
- then
765
- Cifthenelse
766
- ( Cop (Ccmpi Cne , [c2; Cconst_int (- 1 , dbg)], dbg),
767
- dbg,
768
- c,
769
- dbg,
770
- mkm1 c1 dbg,
771
- dbg,
772
- kind )
773
- else c))
757
+ let safe_divmod_bi mkop mkm1 ?(dividend_cannot_be_min_int = false ) is_safe
758
+ dividend divisor dbg =
759
+ let is_different_from x = function
760
+ | Cconst_int (n , _ ) -> Nativeint. of_int n <> x
761
+ | Cconst_natint (n , _ ) -> n <> x
762
+ | _ -> false
763
+ in
764
+ bind " divisor" divisor (fun divisor ->
765
+ bind " dividend" dividend (fun dividend ->
766
+ let c = mkop dividend divisor is_safe dbg in
767
+ if not Arch. division_crashes_on_overflow
768
+ then c
769
+ else
770
+ let dividend_cannot_be_min_int =
771
+ dividend_cannot_be_min_int
772
+ || is_different_from Nativeint. min_int dividend
773
+ in
774
+ let divisor_cannot_be_negative_one =
775
+ is_different_from (- 1n ) divisor
776
+ in
777
+ if dividend_cannot_be_min_int || divisor_cannot_be_negative_one
778
+ then c
779
+ else
780
+ Cifthenelse
781
+ ( Cop (Ccmpi Cne , [divisor; Cconst_int (- 1 , dbg)], dbg),
782
+ dbg,
783
+ c,
784
+ dbg,
785
+ mkm1 dividend dbg,
786
+ dbg,
787
+ Any )))
774
788
775
- let safe_div_bi is_safe =
776
- safe_divmod_bi div_int Any is_safe (fun c1 dbg ->
789
+ let safe_div_bi =
790
+ safe_divmod_bi div_int (fun c1 dbg ->
777
791
Cop (Csubi , [Cconst_int (0 , dbg); c1], dbg))
778
792
779
- let safe_mod_bi is_safe =
780
- safe_divmod_bi mod_int Any is_safe (fun _ dbg -> Cconst_int (0 , dbg))
793
+ let safe_mod_bi = safe_divmod_bi mod_int (fun _ dbg -> Cconst_int (0 , dbg))
781
794
782
795
(* Bool *)
783
796
@@ -1500,6 +1513,37 @@ let setfield_unboxed_vec128 arr ~index_in_words newval dbg =
1500
1513
[field_address; newval],
1501
1514
dbg ))
1502
1515
1516
+ let get_field_unboxed ~dbg memory_chunk mutability block ~index_in_words =
1517
+ match (memory_chunk : memory_chunk ) with
1518
+ | Single { reg = Float32 } ->
1519
+ get_field_unboxed_float32 mutability ~block ~index: index_in_words dbg
1520
+ | Double ->
1521
+ unboxed_float_array_ref mutability ~block ~index: index_in_words dbg
1522
+ | Onetwentyeight_unaligned | Onetwentyeight_aligned ->
1523
+ get_field_unboxed_vec128 mutability ~block ~index_in_words dbg
1524
+ | Thirtytwo_signed ->
1525
+ get_field_unboxed_int32 mutability ~block ~index: index_in_words dbg
1526
+ | Word_int ->
1527
+ get_field_unboxed_int64_or_nativeint mutability ~block ~index: index_in_words
1528
+ dbg
1529
+ | Word_val ->
1530
+ Misc. fatal_error " cannot use get_field_unboxed with a heap block"
1531
+ | _ -> Misc. fatal_error " get_field_unboxed: unexpected memory chunk"
1532
+
1533
+ let set_field_unboxed ~dbg memory_chunk block ~index_in_words newval =
1534
+ match (memory_chunk : memory_chunk ) with
1535
+ | Single { reg = Float32 } ->
1536
+ setfield_unboxed_float32 block index_in_words newval dbg
1537
+ | Double -> float_array_set block index_in_words newval dbg
1538
+ | Onetwentyeight_unaligned | Onetwentyeight_aligned ->
1539
+ setfield_unboxed_vec128 block ~index_in_words newval dbg
1540
+ | Thirtytwo_signed -> setfield_unboxed_int32 block index_in_words newval dbg
1541
+ | Word_int ->
1542
+ setfield_unboxed_int64_or_nativeint block index_in_words newval dbg
1543
+ | Word_val ->
1544
+ Misc. fatal_error " cannot use set_field_unboxed with a heap block"
1545
+ | _ -> Misc. fatal_error " set_field_unboxed : unexpected memory chunk"
1546
+
1503
1547
(* String length *)
1504
1548
1505
1549
(* Length of string block *)
@@ -2010,6 +2054,40 @@ let zero_extend_63 dbg e =
2010
2054
let e = low_63 dbg e in
2011
2055
Cop (Cand , [e; natint_const_untagged dbg 0x7FFF_FFFF_FFFF_FFFFn ], dbg)
2012
2056
2057
+ let zero_extend ~bits ~dbg e =
2058
+ assert (0 < bits && bits < = arch_bits);
2059
+ if bits = arch_bits
2060
+ then e
2061
+ else
2062
+ match bits with
2063
+ | 63 -> zero_extend_63 dbg e
2064
+ | 32 -> zero_extend_32 dbg e
2065
+ | bits -> Misc. fatal_errorf " zero_extend not implemented for %d bits" bits
2066
+
2067
+ let sign_extend ~bits ~dbg e =
2068
+ assert (0 < bits && bits < = arch_bits);
2069
+ if bits = arch_bits
2070
+ then e
2071
+ else
2072
+ match bits with
2073
+ | 63 -> sign_extend_63 dbg e
2074
+ | 32 -> sign_extend_32 dbg e
2075
+ | bits -> Misc. fatal_errorf " sign_extend not implemented for %d bits" bits
2076
+
2077
+ let low_bits ~bits ~(dbg : Debuginfo.t ) e =
2078
+ assert (0 < bits && bits < = arch_bits);
2079
+ if bits = arch_bits
2080
+ then e
2081
+ else
2082
+ match bits with
2083
+ | 63 -> low_63 dbg e
2084
+ | 32 -> low_32 dbg e
2085
+ | bits -> Misc. fatal_errorf " low_bits not implemented for %d bits" bits
2086
+
2087
+ let ignore_low_bits ~bits ~dbg :(_ : Debuginfo.t ) e =
2088
+ assert (0 < = bits && bits < = arch_bits);
2089
+ if bits = 0 then e else ignore_low_bit_int e
2090
+
2013
2091
let and_int e1 e2 dbg =
2014
2092
let is_mask32 = function
2015
2093
| Cconst_natint (0xFFFF_FFFFn , _ ) -> true
@@ -3504,15 +3582,6 @@ let xor_int_caml arg1 arg2 dbg =
3504
3582
Cconst_int (1 , dbg) ],
3505
3583
dbg )
3506
3584
3507
- let lsl_int_caml arg1 arg2 dbg =
3508
- incr_int (lsl_int (decr_int arg1 dbg) (untag_int arg2 dbg) dbg) dbg
3509
-
3510
- let lsr_int_caml arg1 arg2 dbg =
3511
- Cop (Cor , [lsr_int arg1 (untag_int arg2 dbg) dbg; Cconst_int (1 , dbg)], dbg)
3512
-
3513
- let asr_int_caml arg1 arg2 dbg =
3514
- Cop (Cor , [asr_int arg1 (untag_int arg2 dbg) dbg; Cconst_int (1 , dbg)], dbg)
3515
-
3516
3585
type ternary_primitive =
3517
3586
expression -> expression -> expression -> Debuginfo .t -> expression
3518
3587
0 commit comments