-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add bitvector library #284
Draft
filipeom
wants to merge
6
commits into
formalsec:main
Choose a base branch
from
filipeom:add-bitvector
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
d232f97
Add bitvector library
filipeom 7f9906b
Add bitvector unit tests
filipeom dbc082c
Refactor tests with new API
filipeom a11cd17
Start making migration from `Num (IXX)` to `Bitv`
filipeom 9b08df5
Update `CHANGES.md`
filipeom 34f6e9f
Bump colibri2 pin
filipeom File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
(executable | ||
(package smtml) | ||
(name main) | ||
(public_name smtml) | ||
(libraries cmdliner smtml) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# This file is generated by dune, edit dune-project instead | ||
opam-version: "2.0" | ||
synopsis: "Another Arbitrary-Width Bitvectors using the Zarith Library" | ||
description: "Arbitrary-Width Bitvectors using the Zarith Library" | ||
maintainer: ["Filipe Marques <[email protected]>"] | ||
authors: [ | ||
"João Pereira <[email protected]>" | ||
"Filipe Marques <[email protected]>" | ||
"Hichem Rami Ait El Hara <[email protected]>" | ||
"Léo Andrès <[email protected]>" | ||
"Arthur Carcano <[email protected]>" | ||
"Pierre Chambart <[email protected]>" | ||
"José Fragoso Santos <[email protected]>" | ||
] | ||
license: "MIT" | ||
homepage: "https://github.com/formalsec/smtml" | ||
doc: "https://formalsec.github.io/smtml/smtml/index.html" | ||
bug-reports: "https://github.com/formalsec/smtml/issues" | ||
depends: [ | ||
"dune" {>= "3.10"} | ||
"ocaml" {>= "4.14.0"} | ||
"zarith" | ||
"odoc" {with-doc} | ||
] | ||
build: [ | ||
["dune" "subst"] {dev} | ||
[ | ||
"dune" | ||
"build" | ||
"-p" | ||
name | ||
"-j" | ||
jobs | ||
"@install" | ||
"@runtest" {with-test} | ||
"@doc" {with-doc} | ||
] | ||
] | ||
dev-repo: "git+https://github.com/formalsec/smtml.git" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
file "src/colibri2_mappings.ml" | ||
file "src/bitwuzla_mappings.ml" | ||
file "src/cvc5_mappings.ml" | ||
file "src/smtml/colibri2_mappings.ml" | ||
file "src/smtml/bitwuzla_mappings.ml" | ||
file "src/smtml/cvc5_mappings.ml" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
type t = | ||
{ value : Z.t | ||
; width : int | ||
} | ||
|
||
let mask width = Z.pred (Z.shift_left Z.one width) | ||
|
||
let make v m = | ||
let masked_value = Z.logand v (mask m) in | ||
{ value = masked_value; width = m } | ||
|
||
let view { value; _ } = value | ||
|
||
let numbits { width; _ } = width | ||
|
||
let equal a b = Z.equal a.value b.value && a.width = b.width | ||
|
||
let compare a b = Z.compare a.value b.value | ||
|
||
let msb bv = Z.testbit bv.value (bv.width - 1) | ||
|
||
let to_signed bv = | ||
let msb = msb bv in | ||
if msb then Z.sub bv.value (Z.shift_left Z.one bv.width) else bv.value | ||
|
||
let pp fmt bv = Z.pp_print fmt bv.value | ||
|
||
(* Unop *) | ||
let neg bv = make (Z.neg bv.value) bv.width | ||
|
||
let lognot a = make (Z.lognot a.value) a.width | ||
|
||
let clz bv = | ||
let rec count_zeros i = | ||
if i >= bv.width || Z.testbit bv.value (bv.width - 1 - i) then i | ||
else count_zeros (i + 1) | ||
in | ||
make (Z.of_int @@ count_zeros 0) bv.width | ||
|
||
let ctz bv = | ||
let rec count_zeros i = | ||
if i >= bv.width || Z.testbit bv.value i then i else count_zeros (i + 1) | ||
in | ||
make (Z.of_int @@ count_zeros 0) bv.width | ||
|
||
let popcnt bv = make (Z.of_int @@ Z.popcount bv.value) bv.width | ||
|
||
(* Binop *) | ||
let add a b = | ||
assert (a.width = b.width); | ||
make (Z.add a.value b.value) a.width | ||
|
||
let sub a b = | ||
assert (a.width = b.width); | ||
make (Z.sub a.value b.value) a.width | ||
|
||
let mul a b = | ||
assert (a.width = b.width); | ||
make (Z.mul a.value b.value) a.width | ||
|
||
let div a b = | ||
assert (a.width = b.width); | ||
if Z.equal b.value Z.zero then invalid_arg "division by zero"; | ||
make (Z.div (to_signed a) (to_signed b)) a.width | ||
|
||
let div_u a b = | ||
assert (a.width = b.width); | ||
if Z.equal b.value Z.zero then invalid_arg "division by zero"; | ||
make (Z.div a.value b.value) a.width | ||
|
||
let logand a b = | ||
assert (a.width = b.width); | ||
make (Z.logand a.value b.value) a.width | ||
|
||
let logor a b = | ||
assert (a.width = b.width); | ||
make (Z.logor a.value b.value) a.width | ||
|
||
let logxor a b = | ||
assert (a.width = b.width); | ||
make (Z.logxor a.value b.value) a.width | ||
|
||
let shl a n = | ||
let n = Z.to_int n.value in | ||
make (Z.shift_left a.value n) a.width | ||
|
||
let ashr a n = | ||
let n = Z.to_int n.value in | ||
let signed_value = to_signed a in | ||
make (Z.shift_right signed_value n) a.width | ||
|
||
let lshr a n = | ||
let n = Z.to_int n.value in | ||
make (Z.shift_right_trunc a.value n) a.width | ||
|
||
let rem a b = | ||
assert (a.width = b.width); | ||
if Z.equal b.value Z.zero then invalid_arg "division by zero"; | ||
make (Z.rem (to_signed a) (to_signed b)) a.width | ||
|
||
let rem_u a b = | ||
assert (a.width = b.width); | ||
if Z.equal b.value Z.zero then invalid_arg "division by zero"; | ||
make (Z.rem a.value b.value) a.width | ||
|
||
let rotate_left bv n = | ||
let n = Z.to_int n.value mod bv.width in | ||
let left_part = Z.shift_left bv.value n in | ||
let right_part = Z.shift_right bv.value (bv.width - n) in | ||
let rotated = Z.logor left_part right_part in | ||
make rotated bv.width | ||
|
||
let rotate_right bv n = | ||
let n = Z.to_int n.value mod bv.width in | ||
let right_part = Z.shift_right bv.value n in | ||
let left_part = Z.shift_left bv.value (bv.width - n) in | ||
let rotated = Z.logor left_part right_part in | ||
make rotated bv.width | ||
|
||
(* Relop *) | ||
let lt_u a b = Z.lt a.value b.value | ||
|
||
let gt_u a b = Z.gt a.value b.value | ||
|
||
let le_u a b = Z.leq a.value b.value | ||
|
||
let ge_u a b = Z.geq a.value b.value | ||
|
||
let lt a b = Z.lt (to_signed a) (to_signed b) | ||
|
||
let gt a b = Z.gt (to_signed a) (to_signed b) | ||
|
||
let le a b = Z.leq (to_signed a) (to_signed b) | ||
|
||
let ge a b = Z.geq (to_signed a) (to_signed b) | ||
|
||
(* Extract and concat *) | ||
let concat a b = | ||
let new_width = a.width + b.width in | ||
let shifted = Z.shift_left a.value b.width in | ||
let combined = Z.logor shifted b.value in | ||
make combined new_width | ||
|
||
let extract bv ~high ~low = | ||
assert (high <= bv.width && low >= 0 && low < high); | ||
let width = high - low + 1 in | ||
let shifted = Z.shift_right bv.value low in | ||
let extracted = Z.logand shifted (mask width) in | ||
make extracted width | ||
|
||
(* Cvtop *) | ||
let zero_extend width bv = | ||
let new_width = bv.width + width in | ||
make bv.value new_width | ||
|
||
let sign_extend width bv = | ||
let new_width = bv.width + width in | ||
let msb = msb bv in | ||
let sign_mask = | ||
if msb then | ||
let shift_amount = bv.width in | ||
Z.shift_left (mask width) shift_amount | ||
else Z.zero | ||
in | ||
let extended = Z.logor bv.value sign_mask in | ||
make extended new_width |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
type t | ||
|
||
val make : Z.t -> int -> t | ||
|
||
val view : t -> Z.t | ||
|
||
val numbits : t -> int | ||
|
||
val equal : t -> t -> bool | ||
|
||
val compare : t -> t -> int | ||
|
||
val pp : Format.formatter -> t -> unit | ||
|
||
val neg : t -> t | ||
|
||
val lognot : t -> t | ||
|
||
val clz : t -> t | ||
|
||
val ctz : t -> t | ||
|
||
val popcnt : t -> t | ||
|
||
val add : t -> t -> t | ||
|
||
val sub : t -> t -> t | ||
|
||
val mul : t -> t -> t | ||
|
||
val div : t -> t -> t | ||
|
||
val div_u : t -> t -> t | ||
|
||
val logand : t -> t -> t | ||
|
||
val logor : t -> t -> t | ||
|
||
val logxor : t -> t -> t | ||
|
||
val shl : t -> t -> t | ||
|
||
val ashr : t -> t -> t | ||
|
||
val lshr : t -> t -> t | ||
|
||
val rem : t -> t -> t | ||
|
||
val rem_u : t -> t -> t | ||
|
||
val rotate_left : t -> t -> t | ||
|
||
val rotate_right : t -> t -> t | ||
|
||
val lt : t -> t -> bool | ||
|
||
val lt_u : t -> t -> bool | ||
|
||
val gt : t -> t -> bool | ||
|
||
val gt_u : t -> t -> bool | ||
|
||
val le : t -> t -> bool | ||
|
||
val le_u : t -> t -> bool | ||
|
||
val ge : t -> t -> bool | ||
|
||
val ge_u : t -> t -> bool | ||
|
||
val concat : t -> t -> t | ||
|
||
val extract : t -> high:int -> low:int -> t | ||
|
||
val zero_extend : int -> t -> t | ||
|
||
val sign_extend : int -> t -> t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
(library | ||
(wrapped false) | ||
(name bitvector) | ||
(public_name bitvector) | ||
(modules bitvector) | ||
(libraries zarith)) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line can be removed