Skip to content

Commit

Permalink
Bring Owi's missing simplifications into extract2 and concat3
Browse files Browse the repository at this point in the history
  • Loading branch information
filipeom committed Feb 27, 2025
1 parent 3d65b8a commit 1c60420
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 2 deletions.
50 changes: 48 additions & 2 deletions src/expr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -459,12 +459,29 @@ let extract' (hte : t) ~(high : int) ~(low : int) : t =
[@@inline]

let extract (hte : t) ~(high : int) ~(low : int) : t =
match view hte with
| Val (Num (I64 x)) ->
match (view hte, high, low) with
| Val (Num (I64 x)), high, low ->
let x' = nland64 (Int64.shift_right x (low * 8)) (high - low) in
value (Num (I64 x'))
| Concat (_, e), 4, 0 when Ty.size (ty e) = 4 -> e
| Concat (e, _), 8, 4 when Ty.size (ty e) = 4 -> e
| _ -> if high - low = Ty.size (ty hte) then hte else extract' hte ~high ~low

let extract2 (hte : t) (pos : int) : t =
match view hte with
| Val (Num (I32 i)) ->
let i' = Int32.(to_int @@ logand 0xffl @@ shift_right i (pos * 8)) in
value (Num (I8 i'))
| Val (Num (I64 i)) ->
let i' = Int64.(to_int @@ logand 0xffL @@ shift_right i (pos * 8)) in
value (Num (I8 i'))
| Cvtop
( _
, (Zero_extend 24 | Sign_extend 24)
, ({ node = Symbol { ty = Ty_bitv 8; _ }; _ } as sym) ) ->
sym
| _ -> make (Extract (hte, pos + 1, pos))

let concat' (msb : t) (lsb : t) : t = make (Concat (msb, lsb)) [@@inline]

let concat (msb : t) (lsb : t) : t =
Expand Down Expand Up @@ -499,6 +516,35 @@ let concat (msb : t) (lsb : t) : t =
concat' (extract' (value (Num (I64 x))) ~high:(d1 + d2) ~low:0) se
| _ -> concat' msb lsb

(* TODO: don't rebuild so many values it generates unecessary hc lookups *)
let merge_extracts (e1, h, m1) (e2, m2, l) =
let ty = ty e1 in
if m1 = m2 && equal e1 e2 then
if h - l = Ty.size ty then e1 else make (Extract (e1, h, l))
else make (Concat (make (Extract (e1, h, m1)), make (Extract (e2, m2, l))))

let concat3 ~msb ~lsb offset =
assert (offset > 0 && offset <= 8);
match (view msb, view lsb) with
| Val (Num (I8 i1)), Val (Num (I8 i2)) ->
value (Num (I32 Int32.(logor (shift_left (of_int i1) 8) (of_int i2))))
| Val (Num (I8 i1)), Val (Num (I32 i2)) ->
let offset = offset * 8 in
if offset < 32 then
value (Num (I32 Int32.(logor (shift_left (of_int i1) offset) i2)))
else
let i1' = Int64.of_int i1 in
let i2' = Int64.of_int32 i2 in
value (Num (I64 Int64.(logor (shift_left i1' offset) i2')))
| Val (Num (I8 i1)), Val (Num (I64 i2)) ->
let offset = offset * 8 in
value (Num (I64 Int64.(logor (shift_left (of_int i1) offset) i2)))
| Extract (e1, h, m1), Extract (e2, m2, l) ->
merge_extracts (e1, h, m1) (e2, m2, l)
| Extract (e1, h, m1), Concat ({ node = Extract (e2, m2, l); _ }, e3) ->
make (Concat (merge_extracts (e1, h, m1) (e2, m2, l), e3))
| _ -> make (Concat (msb, lsb))

let rec simplify_expr ?(rm_extract = true) (hte : t) : t =
match view hte with
| Val _ | Symbol _ -> hte
Expand Down
4 changes: 4 additions & 0 deletions src/expr.mli
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,16 @@ val extract : t -> high:int -> low:int -> t
(** Dumb extract constructor, no simplifications *)
val extract' : t -> high:int -> low:int -> t

val extract2 : t -> int -> t

(** Smart concat constructor, applies simplifications at constructor level *)
val concat : t -> t -> t

(** Dumb concat constructor, no simplifications *)
val concat' : t -> t -> t

val concat3 : msb:t -> lsb:t -> int -> t

(** Applies expression simplifications until a fixpoint *)
val simplify : t -> t

Expand Down

0 comments on commit 1c60420

Please sign in to comment.