1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
(* SPDX-License-Identifier: AGPL-3.0-or-later *)
(* Copyright © 2021-2026 OCamlPro *)
(* Written by the Owi programmers *)
include Int32
type t = int32
let wrap_i64 x = Int64.to_int32 x
let trunc_f32_s x =
if Float32.ne x x then Error `Conversion_to_integer
else
let xf = Float32.to_float x in
if
let xf = Float64.of_float xf in
let mif = Int32.(to_float min_int) in
Float64.(le (of_float ~-.mif) xf) || Float64.(lt xf (of_float mif))
then Error `Integer_overflow
else Ok (Int32.of_float xf)
let trunc_f32_u x =
if Float32.ne x x then Error `Conversion_to_integer
else
let xf = Float32.to_float x in
if
let xf = Float64.of_float xf in
Float64.(le (of_float @@ (-.Int32.(to_float min_int) *. 2.0)) xf)
|| Float64.(le xf (Float64.of_float ~-.1.0))
then Error `Integer_overflow
else Ok Int64.(to_int32 (of_float xf))
let trunc_f64_s x =
if Float64.ne x x then Error `Conversion_to_integer
else if
let mif = Int32.(to_float min_int) in
Float64.(le (of_float @@ -.mif) x)
|| Float64.(le x (of_float @@ (mif -. 1.0)))
then Error `Integer_overflow
else Ok (Int32.of_float (Float64.to_float x))
let trunc_f64_u x =
if Float64.ne x x then Error `Conversion_to_integer
else if
let mif = Int32.to_float Int32.min_int in
Float64.(le (of_float @@ (-.mif *. 2.0)) x)
|| Float64.(le x (of_float ~-.1.0))
then Error `Integer_overflow
else Ok Int64.(to_int32 (of_float (Float64.to_float x)))
let trunc_sat_f32_s x =
if Float32.ne x x then 0l
else
let xf = Float32.to_float x |> Float64.of_float in
let mif = Int32.(to_float min_int) in
if Float64.(lt xf (of_float mif)) then Int32.min_int
else if Float64.(le (of_float ~-.mif) xf) then Int32.max_int
else Int32.of_float (Float64.to_float xf)
let trunc_sat_f32_u x =
if Float32.ne x x then 0l
else
let xf = Float32.to_float x |> Float64.of_float in
if Float64.(le xf (of_float ~-.1.0)) then 0l
else if Float64.(le (of_float (~-.Int32.(to_float min_int) *. 2.0)) xf) then
-1l
else Int64.(to_int32 @@ of_float (Float64.to_float xf))
let trunc_sat_f64_s x =
if Float64.ne x x then 0l
else if Float64.(le x @@ of_float @@ Int32.(to_float min_int)) then
Int32.min_int
else if Float64.(le (of_float ~-.Int32.(to_float min_int)) x) then
Int32.max_int
else Int32.of_float @@ Float64.to_float x
let trunc_sat_f64_u x =
if Float64.ne x x then 0l
else if Float64.(le x @@ of_float ~-.1.0) then 0l
else if Float64.(le (of_float ~-.(Int32.(to_float min_int) *. 2.0)) x) then
-1l
else Int64.(to_int32 (of_float @@ Float64.to_float x))
let reinterpret_f32 = Float32.to_bits
let to_boolean = function 0l -> false | _i -> true
let of_boolean = function false -> 0l | true -> 1l
let of_concrete (v : t) : t = v
let eq_concrete (v1 : t) (v2 : Int32.t) = eq v1 v2
let pp = Fmt.int32
let of_int32 (v : int32) : t = v
let to_int32 (v : t) : int32 = v
let min_int = Int32.min_int
let eqz (v : t) = eq v zero
let ( = ) = eq
let ( + ) = add
let of_i16x2 a b =
let lower = logand (of_int a) 0xFFFFl in
let upper = shl (of_int b) 16l in
logor lower upper
let of_i8x4 a b c d =
of_i16x2 (Concrete_i16.of_i8x2 a b) (Concrete_i16.of_i8x2 c d)
let narrow_i16_s x =
if lt x (-32768l) then -32768 else if lt 32767l x then 32767 else to_int x
let narrow_i16_u x =
let x = logand x 0xffff_ffffl in
if lt x 0l then 0 else if lt 65535l x then 65535 else to_int x
let neg x = sub 0l x
let abs x = if lt x 0l then neg x else x
let min_s x y = if lt x y then x else y
let min_u x y = if lt (logxor x min_int) (logxor y min_int) then x else y
let max_s x y = if lt x y then y else x
let max_u x y = if lt (logxor x min_int) (logxor y min_int) then y else x