Skip to content

Commit e2bcbc7

Browse files
committed
WIP
1 parent 7f9906b commit e2bcbc7

File tree

7 files changed

+86
-17
lines changed

7 files changed

+86
-17
lines changed

src/bitvector/bitvector.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@ let clz bv =
3535
if i >= bv.width || Z.testbit bv.value (bv.width - 1 - i) then i
3636
else count_zeros (i + 1)
3737
in
38-
count_zeros 0
38+
make (Z.of_int @@ count_zeros 0) bv.width
3939

4040
let ctz bv =
4141
let rec count_zeros i =
4242
if i >= bv.width || Z.testbit bv.value i then i else count_zeros (i + 1)
4343
in
44-
count_zeros 0
44+
make (Z.of_int @@ count_zeros 0) bv.width
4545

46-
let popcnt bv = Z.popcount bv.value
46+
let popcnt bv = make (Z.of_int @@ Z.popcount bv.value) bv.width
4747

4848
(* Binop *)
4949
let add a b =

src/bitvector/bitvector.mli

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ val neg : t -> t
1616

1717
val lognot : t -> t
1818

19-
val clz : t -> int
19+
val clz : t -> t
2020

21-
val ctz : t -> int
21+
val ctz : t -> t
2222

23-
val popcnt : t -> int
23+
val popcnt : t -> t
2424

2525
val add : t -> t -> t
2626

src/smtml/dune

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
(flags
5656
(:standard -open Smtml_prelude))
5757
(libraries
58+
bitvector
5859
bos
5960
cmdliner
6061
dolmen

src/smtml/eval.ml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,65 @@ module Lst = struct
439439
Fmt.failwith {|naryop: Unsupported list operator "%a"|} Ty.Naryop.pp op
440440
end
441441

442+
module Bitv = struct
443+
let to_value (bv : Bitvector.t) : Value.t = Bitv bv [@@inline]
444+
445+
let of_value (n : int) (op : op_type) (v : Value.t) =
446+
of_arg
447+
(function Bitv bv -> bv | _ -> raise_notrace (Value (Ty_bitv 0)))
448+
n v op
449+
[@@inline]
450+
451+
let unop (op : Ty.Unop.t) (v : Value.t) : Value.t =
452+
let f =
453+
match op with
454+
| Neg -> Bitvector.neg
455+
| Not -> Bitvector.lognot
456+
| Clz -> Bitvector.clz
457+
| Ctz -> Bitvector.ctz
458+
| _ -> Fmt.failwith {|unop: Unsupported i32 operator "%a"|} Ty.Unop.pp op
459+
in
460+
to_value (f (of_value 1 (`Unop op) v))
461+
462+
let binop op v1 v2 =
463+
let f =
464+
match op with
465+
| Ty.Binop.Add -> Bitvector.add
466+
| Sub -> Bitvector.sub
467+
| Mul -> Bitvector.mul
468+
| Div -> Bitvector.div
469+
| DivU -> Bitvector.div_u
470+
| Rem -> Bitvector.rem
471+
| RemU -> Bitvector.rem_u
472+
| And -> Bitvector.logand
473+
| Or -> Bitvector.logor
474+
| Xor -> Bitvector.logxor
475+
| Shl -> Bitvector.shl
476+
| ShrL -> Bitvector.lshr
477+
| ShrA -> Bitvector.ashr
478+
| Rotl -> Bitvector.rotate_left
479+
| Rotr -> Bitvector.rotate_right
480+
| _ ->
481+
Fmt.failwith {|binop: Unsupported i32 operator "%a"|} Ty.Binop.pp op
482+
in
483+
to_value (f (of_value 1 (`Binop op) v1) (of_value 2 (`Binop op) v2))
484+
485+
let relop (op : Ty.Relop.t) (v1 : Value.t) (v2 : Value.t) : bool =
486+
let f =
487+
match op with
488+
| Lt -> Bitvector.lt
489+
| LtU -> Bitvector.lt_u
490+
| Le -> Bitvector.le
491+
| LeU -> Bitvector.le_u
492+
| Gt -> Bitvector.gt
493+
| GtU -> Bitvector.gt_u
494+
| Ge -> Bitvector.ge
495+
| GeU -> Bitvector.ge_u
496+
| Eq | Ne -> assert false
497+
in
498+
f (of_value 1 (`Relop op) v1) (of_value 2 (`Relop op) v2)
499+
end
500+
442501
module I32 = struct
443502
let to_value (i : int32) : Value.t = Num (I32 i) [@@inline]
444503

src/smtml/mappings.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ module Make (M_with_make : M_with_make) : S_with_fresh = struct
547547
| Num (I64 x) -> I64.v x
548548
| Num (F32 x) -> Float32_impl.v x
549549
| Num (F64 x) -> Float64_impl.v x
550+
| Bitv _bv -> assert false
550551
| List _ | App _ | Unit | Nothing -> assert false
551552

552553
let unop = function

src/smtml/value.ml

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ type t =
1212
| Real of float
1313
| Str of string
1414
| Num of Num.t
15+
| Bitv of Bitvector.t
1516
| List of t list
1617
| App : [> `Op of string ] * t list -> t
1718
| Nothing
@@ -24,6 +25,7 @@ let type_of (v : t) : Ty.t =
2425
| Real _ -> Ty_real
2526
| Str _ -> Ty_str
2627
| Num n -> Num.type_of n
28+
| Bitv bv -> Ty_bitv (Bitvector.numbits bv)
2729
| List _ -> Ty_list
2830
| App _ -> Ty_app
2931
| Nothing -> Ty_none
@@ -36,9 +38,10 @@ let discr = function
3638
| Real _ -> 4
3739
| Str _ -> 5
3840
| Num _ -> 6
39-
| List _ -> 7
40-
| App _ -> 8
41-
| Nothing -> 9
41+
| Bitv _ -> 7
42+
| List _ -> 8
43+
| App _ -> 9
44+
| Nothing -> 10
4245

4346
let rec compare (a : t) (b : t) : int =
4447
match (a, b) with
@@ -49,28 +52,30 @@ let rec compare (a : t) (b : t) : int =
4952
| Real a, Real b -> Float.compare a b
5053
| Str a, Str b -> String.compare a b
5154
| Num a, Num b -> Num.compare a b
55+
| Bitv a, Bitv b -> Bitvector.compare a b
5256
| List a, List b -> List.compare compare a b
5357
| App (`Op op1, vs1), App (`Op op2, vs2) ->
5458
let c = String.compare op1 op2 in
5559
if c = 0 then List.compare compare vs1 vs2 else c
56-
| ( ( True | False | Unit | Int _ | Real _ | Str _ | Num _ | List _ | App _
57-
| Nothing )
60+
| ( ( True | False | Unit | Int _ | Real _ | Str _ | Num _ | Bitv _ | List _
61+
| App _ | Nothing )
5862
, _ ) ->
5963
(* TODO: I don't know if this is always semantically correct *)
6064
Int.compare (discr a) (discr b)
6165

6266
let rec equal (v1 : t) (v2 : t) : bool =
6367
match (v1, v2) with
6468
| True, True | False, False | Unit, Unit | Nothing, Nothing -> true
65-
| Int x1, Int x2 -> Int.equal x1 x2
66-
| Real x1, Real x2 -> Float.equal x1 x2
67-
| Str x1, Str x2 -> String.equal x1 x2
68-
| Num x1, Num x2 -> Num.equal x1 x2
69+
| Int a, Int b -> Int.equal a b
70+
| Real a, Real b -> Float.equal a b
71+
| Str a, Str b -> String.equal a b
72+
| Num a, Num b -> Num.equal a b
73+
| Bitv a, Bitv b -> Bitvector.equal a b
6974
| List l1, List l2 -> List.equal equal l1 l2
7075
| App (`Op op1, vs1), App (`Op op2, vs2) ->
7176
String.equal op1 op2 && List.equal equal vs1 vs2
72-
| ( ( True | False | Unit | Int _ | Real _ | Str _ | Num _ | List _ | App _
73-
| Nothing )
77+
| ( ( True | False | Unit | Int _ | Real _ | Str _ | Num _ | Bitv _ | List _
78+
| App _ | Nothing )
7479
, _ ) ->
7580
false
7681

@@ -85,6 +90,7 @@ let rec pp fmt = function
8590
| Int x -> Fmt.int fmt x
8691
| Real x -> Fmt.pf fmt "%F" x
8792
| Num x -> Num.pp_no_type fmt x
93+
| Bitv x -> Bitvector.pp fmt x
8894
| Str x -> Fmt.pf fmt "%S" x
8995
| List l -> (Fmt.hovbox ~indent:1 (Fmt.list ~sep:Fmt.comma pp)) fmt l
9096
| App (`Op op, vs) ->
@@ -126,6 +132,7 @@ let rec to_json (v : t) : Yojson.Basic.t =
126132
| Real real -> `Float real
127133
| Str str -> `String str
128134
| Num n -> Num.to_json n
135+
| Bitv bv -> `String (Fmt.str "%a" Bitvector.pp bv)
129136
| List l -> `List (List.map to_json l)
130137
| Nothing -> `Null
131138
| App _ -> assert false

src/smtml/value.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ type t =
1010
| Real of float
1111
| Str of string
1212
| Num of Num.t
13+
| Bitv of Bitvector.t
1314
| List of t list
1415
| App : [> `Op of string ] * t list -> t
1516
| Nothing

0 commit comments

Comments
 (0)