Skip to content

Commit

Permalink
Add ZRange.bitwidth, ZRange.of_bitwidth (#2041)
Browse files Browse the repository at this point in the history
  • Loading branch information
JasonGross authored Mar 8, 2025
1 parent 2d55a49 commit c177f8e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/AbstractInterpretation/ZRange.v
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ Module Compilers.
| base.type.list A => list (interp A)
| base.type.option A => option (interp A)
end%type.
Fixpoint bitwidth {t} : interp t -> binterp t
:= match t with
| base.type.type_base base.type.Z => fun r => ZRange.bitwidth r
| base.type.type_base _ as t
| base.type.unit as t
=> fun x => x
| base.type.prod A B => fun '(a, b) => (@bitwidth A a, @bitwidth B b)
| base.type.list A => List.map (@bitwidth A)
| base.type.option A => option_map (@bitwidth A)
end.
Fixpoint of_bitwidth (signed : bool) {t} : binterp t -> interp t
:= match t with
| base.type.type_base base.type.Z => fun r => ZRange.of_bitwidth signed r
| base.type.type_base _ as t
| base.type.unit as t
=> fun x => x
| base.type.prod A B => fun '(a, b) => (@of_bitwidth signed A a, @of_bitwidth signed B b)
| base.type.list A => List.map (@of_bitwidth signed A)
| base.type.option A => option_map (@of_bitwidth signed A)
end%type.
Notation of_bitwidth_unsigned := (@of_bitwidth false).
Notation of_bitwidth_signed := (@of_bitwidth true).
Fixpoint map_ranges (f : zrange -> zrange) {t} : interp t -> interp t
:= match t with
| base.type.type_base base.type.Z => f
Expand Down Expand Up @@ -406,6 +428,18 @@ Module Compilers.
| type.base x => @base.is_bounded_by x
| type.arrow s d => fun _ _ => false
end.
Fixpoint bitwidth (signed : bool) {t} : interp t -> einterp t
:= match t with
| type.base x => @base.bitwidth x
| type.arrow s d => fun fr sz => @bitwidth signed d (fr (@of_bitwidth signed s sz))
end
with of_bitwidth (signed : bool) {t} : einterp t -> interp t
:= match t with
| type.base x => @base.of_bitwidth signed x
| type.arrow s d => fun fr sz => @of_bitwidth signed d (fr (@bitwidth signed s sz))
end.
Notation of_bitwidth_unsigned := (@of_bitwidth false).
Notation of_bitwidth_signed := (@of_bitwidth true).
Module option.
(** turn a [type] into a [Set] describing the type of optional
bounds on that base type; bounds on a [Z] may be either a
Expand Down
12 changes: 12 additions & 0 deletions src/Util/ZRange/Operations.v
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,18 @@ Module ZRange.

Local Notation eta v := r[ lower v ~> upper v ].

Definition bitwidth (v : zrange) : Z
:= let bitwidth_of z := (if (z =? 0) then 0 else if (z <? 0) then Z.log2_up (-z) else Z.log2_up (z+1))%Z in
Z.max (bitwidth_of (lower v)) (bitwidth_of (upper v)).

Definition of_bitwidth (signed : bool) (bitwidth : Z) : zrange
:= if signed
then r[ -2 ^ (bitwidth - 1) ~> 2 ^ (bitwidth - 1) - 1 ]
else r[ 0 ~> 2 ^ bitwidth - 1 ].

Notation of_bitwidth_unsigned := (of_bitwidth false).
Notation of_bitwidth_signed := (of_bitwidth true).

Definition flip (v : zrange) : zrange
:= r[ upper v ~> lower v ].

Expand Down

0 comments on commit c177f8e

Please sign in to comment.