package smtml
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
An SMT solver frontend for OCaml
Install
dune-project
Dependency
Authors
-
JJoão Pereira <joaomhmpereira@tecnico.ulisboa.pt>
-
FFilipe Marques <filipe.s.marques@tecnico.ulisboa.pt>
-
HHichem Rami Ait El Hara <hra@ocamlpro.com>
-
Rredianthus <redopam@pm.me>
-
AArthur Carcano <arthur.carcano@ocamlpro.com>
-
PPierre Chambart <pierre.chambart@ocamlpro.com>
-
JJosé Fragoso Santos <jose.fragoso@tecnico.ulisboa.pt>
Maintainers
Sources
v0.22.0.tar.gz
md5=2ec822c82786736b275c31e850f7d292
sha512=335a1595b0652ca0d5aa50177e47a66467935d586433ad26329d6fa7d9ff6fd3eda51d630c2002278eb6565e8de83e0750b000c0a0f5b453b7ed11ffca3519a2
doc/src/smtml/bitvector.ml.html
Source file bitvector.ml
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 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228type 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 of_int8 v = (* TODO: add a check on v to make sure it is not too big ? *) make (Z.of_int v) 8 let of_int16 v = (* TODO: add a check on v to make sure it is not too big ? *) make (Z.of_int v) 16 let of_int32 v = make (Z.of_int32 v) 32 let of_int64 v = make (Z.of_int64 v) 64 (* Optimized mixer (DJB2 variant). Inlines to simple arithmetic. *) let[@inline] combine h v = (h * 33) + v let hash a = combine (Z.hash a.value) a.width let equal a b = Z.equal a.value b.value && a.width = b.width let eqz v = Z.equal Z.zero v.value let eq_one v = Z.equal Z.one v.value 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 to_int32 v = if numbits v <= 32 then Z.to_int32 (to_signed v) else Fmt.failwith "call to Smtml.Bitvector.to_int32 on a bitvector of size %d" v.width let to_int64 v = if numbits v <= 64 then Z.to_int64 (to_signed v) else Fmt.failwith "call to Smtml.Bitvector.to_int32 on a bitvector of size %d" v.width type printer = [ `Pretty (** Human-readable format. *) | `WithType (** Print with type info. *) ] (** Bitvector pretty printer. By default it prints signed bitvectors. *) let pp_bv fmt bv = let value = to_signed bv in Z.pp_print fmt value let pp_wtype fmt bv = let value = to_signed bv in Fmt.pf fmt "(i%d %a)" bv.width Z.pp_print value let printer = ref pp_bv let set_default_printer = function | `Pretty -> printer := pp_bv | `WithType -> printer := pp_wtype let pp fmt e = !printer fmt e (* 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 raise 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 raise 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 normalize_shift_amount n width = (* FIXME: only works for widths that are powers of 2. *) assert (width > 0 && width land (width - 1) = 0); Z.to_int @@ Z.logand n (Z.of_int (width - 1)) let shl a n = let n = normalize_shift_amount (view n) (numbits a) in make (Z.shift_left a.value n) a.width let ashr a n = let n = normalize_shift_amount (view n) (numbits a) in let signed_value = to_signed a in make (Z.shift_right signed_value n) a.width let lshr a n = let n = normalize_shift_amount (view n) (numbits a) 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 raise 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 raise Division_by_zero; make (Z.rem a.value b.value) a.width let rotate_left bv n = let n = normalize_shift_amount (view n) (numbits bv) 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 = normalize_shift_amount (view n) (numbits bv) 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 let to_string bv = Fmt.str "%a" pp bv let to_json bv = `String (to_string bv)
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>