1 /* Boolector: Satisfiability Modulo Theories (SMT) solver.
2 *
3 * Copyright (C) 2007-2021 by the authors listed in the AUTHORS file.
4 *
5 * This file is part of Boolector.
6 * See COPYING for more information on using this software.
7 */
8
9 #include "btorbv.h"
10 #include "btoraig.h"
11 #include "btoraigvec.h"
12 #include "btorcore.h"
13 #include "utils/btorutil.h"
14
15 #include <limits.h>
16
17 #ifdef BTOR_USE_GMP
18 #include <gmp.h>
19 #endif
20
21 /*------------------------------------------------------------------------*/
22
23 struct BtorBitVector
24 {
25 uint32_t width; /* length of bit vector */
26 #ifdef BTOR_USE_GMP
27 mpz_t val;
28 #else
29 uint32_t len; /* length of 'bits' array */
30
31 /* 'bits' represents the bit vector in 32-bit chunks, first bit of 32-bit bv
32 * in bits[0] is MSB, bit vector is 'filled' from LSB, hence spare bits (if
33 * any) come in front of the MSB and are zeroed out.
34 * E.g., for a bit vector of width 31, representing value 1:
35 *
36 * bits[0] = 0 0000....1
37 * ^ ^--- MSB
38 * |--- spare bit
39 * */
40 BTOR_BV_TYPE bits[];
41 #endif
42 };
43
44 /*------------------------------------------------------------------------*/
45
46 #define BTOR_MASK_REM_BITS(bv) \
47 ((((BTOR_BV_TYPE) 1 << (BTOR_BV_TYPE_BW - 1)) - 1) \
48 >> (BTOR_BV_TYPE_BW - 1 - (bv->width % BTOR_BV_TYPE_BW)))
49
50 /*------------------------------------------------------------------------*/
51
52 #ifndef BTOR_USE_GMP
53 #ifndef NDEBUG
54 static bool
rem_bits_zero_dbg(BtorBitVector * bv)55 rem_bits_zero_dbg (BtorBitVector *bv)
56 {
57 return (bv->width % BTOR_BV_TYPE_BW == 0
58 || (bv->bits[0] >> (bv->width % BTOR_BV_TYPE_BW) == 0));
59 }
60 #endif
61
62 static void
set_rem_bits_to_zero(BtorBitVector * bv)63 set_rem_bits_to_zero (BtorBitVector *bv)
64 {
65 if (bv->width != BTOR_BV_TYPE_BW * bv->len)
66 bv->bits[0] &= BTOR_MASK_REM_BITS (bv);
67 }
68 #endif
69
70 #ifndef NDEBUG
71 static bool
check_bits_sll_dbg(const BtorBitVector * bv,const BtorBitVector * res,uint32_t shift)72 check_bits_sll_dbg (const BtorBitVector *bv,
73 const BtorBitVector *res,
74 uint32_t shift)
75 {
76 assert (bv);
77 assert (res);
78 assert (bv->width == res->width);
79
80 uint32_t i;
81
82 if (shift >= bv->width)
83 {
84 for (i = 0; i < bv->width; i++) assert (btor_bv_get_bit (bv, i) == 0);
85 }
86 else
87 {
88 for (i = 0; shift + i < bv->width; i++)
89 assert (btor_bv_get_bit (bv, i) == btor_bv_get_bit (res, shift + i));
90 }
91
92 return true;
93 }
94 #endif
95
96 /*------------------------------------------------------------------------*/
97
98 BtorBitVector *
btor_bv_new(BtorMemMgr * mm,uint32_t bw)99 btor_bv_new (BtorMemMgr *mm, uint32_t bw)
100 {
101 assert (mm);
102 assert (bw > 0);
103
104 BtorBitVector *res;
105
106 #ifdef BTOR_USE_GMP
107 BTOR_NEW (mm, res);
108 res->width = bw;
109 mpz_init (res->val);
110 #else
111 uint32_t i;
112
113 i = bw / BTOR_BV_TYPE_BW;
114 if (bw % BTOR_BV_TYPE_BW > 0) i += 1;
115
116 assert (i > 0);
117 res =
118 btor_mem_malloc (mm, sizeof (BtorBitVector) + sizeof (BTOR_BV_TYPE) * i);
119 BTOR_CLRN (res->bits, i);
120 res->len = i;
121 assert (res->len);
122 res->width = bw;
123 assert (res->width <= res->len * BTOR_BV_TYPE_BW);
124 #endif
125 return res;
126 }
127
128 BtorBitVector *
btor_bv_new_random(BtorMemMgr * mm,BtorRNG * rng,uint32_t bw)129 btor_bv_new_random (BtorMemMgr *mm, BtorRNG *rng, uint32_t bw)
130 {
131 BtorBitVector *res;
132 #ifdef BTOR_USE_GMP
133 res = btor_bv_new (mm, bw);
134 mpz_urandomb (res->val, *((gmp_randstate_t *) rng->gmp_state), bw);
135 mpz_fdiv_r_2exp (res->val, res->val, bw);
136 #else
137 res = btor_bv_new_random_bit_range (mm, rng, bw, bw - 1, 0);
138 #endif
139 return res;
140 }
141
142 BtorBitVector *
btor_bv_new_random_range(BtorMemMgr * mm,BtorRNG * rng,uint32_t bw,const BtorBitVector * from,const BtorBitVector * to)143 btor_bv_new_random_range (BtorMemMgr *mm,
144 BtorRNG *rng,
145 uint32_t bw,
146 const BtorBitVector *from,
147 const BtorBitVector *to)
148 {
149 assert (mm);
150 assert (rng);
151 assert (bw > 0);
152 assert (bw == from->width);
153 assert (from->width == to->width);
154 assert (btor_bv_compare (from, to) <= 0);
155
156 BtorBitVector *res;
157
158 #ifdef BTOR_USE_GMP
159 mpz_t n_to;
160
161 res = btor_bv_new (mm, bw);
162 mpz_init_set (n_to, to->val);
163 mpz_sub (n_to, n_to, from->val);
164 mpz_add_ui (n_to, n_to, 1);
165
166 mpz_urandomm (res->val, *((gmp_randstate_t *) rng->gmp_state), n_to);
167 mpz_add (res->val, res->val, from->val);
168 mpz_clear (n_to);
169 #else
170 BtorBitVector *resext, *fromext, *toext, *tmp1, *tmp2;
171
172 /* we allow to = 1...1 */
173 fromext = btor_bv_uext (mm, from, 1);
174 toext = btor_bv_uext (mm, to, 1);
175
176 res = btor_bv_new_random (mm, rng, bw);
177 resext = btor_bv_uext (mm, res, 1);
178 btor_bv_free (mm, res);
179
180 tmp1 = btor_bv_inc (mm, toext); // to + 1
181 tmp2 = btor_bv_sub (mm, tmp1, fromext); // to + 1 - from
182 btor_bv_free (mm, tmp1);
183
184 tmp1 = resext;
185 resext = btor_bv_urem (mm, tmp1, tmp2); // res %= to + 1 - from
186 btor_bv_free (mm, tmp1);
187
188 tmp1 = resext;
189 resext = btor_bv_add (mm, tmp1, fromext); // res += from
190
191 btor_bv_free (mm, tmp1);
192 btor_bv_free (mm, tmp2);
193 btor_bv_free (mm, fromext);
194 btor_bv_free (mm, toext);
195
196 res = btor_bv_slice (mm, resext, from->width - 1, 0);
197 btor_bv_free (mm, resext);
198 #endif
199 return res;
200 }
201
202 BtorBitVector *
btor_bv_new_random_bit_range(BtorMemMgr * mm,BtorRNG * rng,uint32_t bw,uint32_t up,uint32_t lo)203 btor_bv_new_random_bit_range (
204 BtorMemMgr *mm, BtorRNG *rng, uint32_t bw, uint32_t up, uint32_t lo)
205 {
206 assert (mm);
207 assert (rng);
208 assert (bw > 0);
209 assert (lo <= up);
210
211 uint32_t i;
212 BtorBitVector *res;
213
214 #ifdef BTOR_USE_GMP
215 res = btor_bv_new_random (mm, rng, bw);
216 #else
217 res = btor_bv_new (mm, bw);
218 for (i = 1; i < res->len; i++)
219 res->bits[i] = (BTOR_BV_TYPE) btor_rng_rand (rng);
220 res->bits[0] = (BTOR_BV_TYPE) btor_rng_pick_rand (
221 rng, 0, ((~0) >> (BTOR_BV_TYPE_BW - bw % BTOR_BV_TYPE_BW)) - 1);
222 set_rem_bits_to_zero (res);
223 #endif
224 for (i = 0; i < lo; i++) btor_bv_set_bit (res, i, 0);
225 for (i = up + 1; i < res->width; i++) btor_bv_set_bit (res, i, 0);
226
227 return res;
228 }
229
230 /*------------------------------------------------------------------------*/
231
232 BtorBitVector *
btor_bv_char_to_bv(BtorMemMgr * mm,const char * assignment)233 btor_bv_char_to_bv (BtorMemMgr *mm, const char *assignment)
234 {
235 assert (mm);
236 assert (assignment);
237 assert (strlen (assignment) > 0);
238
239 BtorBitVector *res;
240 #ifdef BTOR_USE_GMP
241 BTOR_NEW (mm, res);
242 res->width = strlen (assignment);
243 mpz_init_set_str (res->val, assignment, 2);
244 #else
245 res = btor_bv_const (mm, assignment, strlen (assignment));
246 #endif
247 return res;
248 }
249
250 BtorBitVector *
btor_bv_uint64_to_bv(BtorMemMgr * mm,uint64_t value,uint32_t bw)251 btor_bv_uint64_to_bv (BtorMemMgr *mm, uint64_t value, uint32_t bw)
252 {
253 assert (mm);
254 assert (bw > 0);
255
256 BtorBitVector *res;
257
258 #ifdef BTOR_USE_GMP
259 BTOR_NEW (mm, res);
260 res->width = bw;
261 mpz_init_set_ui (res->val, value);
262 mpz_fdiv_r_2exp (res->val, res->val, bw);
263 #else
264 res = btor_bv_new (mm, bw);
265 assert (res->len > 0);
266 res->bits[res->len - 1] = (BTOR_BV_TYPE) value;
267 if (res->width > 32)
268 res->bits[res->len - 2] = (BTOR_BV_TYPE) (value >> BTOR_BV_TYPE_BW);
269
270 set_rem_bits_to_zero (res);
271 assert (rem_bits_zero_dbg (res));
272 #endif
273 return res;
274 }
275
276 BtorBitVector *
btor_bv_int64_to_bv(BtorMemMgr * mm,int64_t value,uint32_t bw)277 btor_bv_int64_to_bv (BtorMemMgr *mm, int64_t value, uint32_t bw)
278 {
279 assert (mm);
280 assert (bw > 0);
281
282 BtorBitVector *res;
283
284 #ifdef BTOR_USE_GMP
285 BTOR_NEW (mm, res);
286 res->width = bw;
287 mpz_init_set_si (res->val, value);
288 mpz_fdiv_r_2exp (res->val, res->val, bw);
289 #else
290 BtorBitVector *tmp;
291 res = btor_bv_new (mm, bw);
292 assert (res->len > 0);
293
294 /* ensure that all bits > 64 are set to 1 in case of negative values */
295 if (value < 0 && bw > 64)
296 {
297 tmp = btor_bv_not (mm, res);
298 btor_bv_free (mm, res);
299 res = tmp;
300 }
301
302 res->bits[res->len - 1] = (BTOR_BV_TYPE) value;
303 if (res->width > 32)
304 res->bits[res->len - 2] = (BTOR_BV_TYPE) (value >> BTOR_BV_TYPE_BW);
305
306 set_rem_bits_to_zero (res);
307 assert (rem_bits_zero_dbg (res));
308 #endif
309 return res;
310 }
311
312 BtorBitVector *
btor_bv_const(BtorMemMgr * mm,const char * str,uint32_t bw)313 btor_bv_const (BtorMemMgr *mm, const char *str, uint32_t bw)
314 {
315 assert (btor_util_check_bin_to_bv (mm, str, bw));
316
317 BtorBitVector *res;
318
319 #ifdef BTOR_USE_GMP
320 BTOR_NEW (mm, res);
321 res->width = bw;
322 mpz_init_set_str (res->val, str, 2);
323 #else
324 uint32_t i, j, bit;
325 res = btor_bv_new (mm, bw);
326 for (i = 0; i < bw; i++)
327 {
328 j = bw - 1 - i;
329 assert (str[j] == '0' || str[j] == '1');
330 bit = str[j] == '0' ? 0 : 1;
331 btor_bv_set_bit (res, i, bit);
332 }
333 #endif
334 return res;
335 }
336
337 BtorBitVector *
btor_bv_constd(BtorMemMgr * mm,const char * str,uint32_t bw)338 btor_bv_constd (BtorMemMgr *mm, const char *str, uint32_t bw)
339 {
340 assert (btor_util_check_dec_to_bv (mm, str, bw));
341
342 BtorBitVector *res;
343
344 #ifdef BTOR_USE_GMP
345 BTOR_NEW (mm, res);
346 res->width = bw;
347 mpz_init_set_str (res->val, str, 10);
348 #else
349 bool is_neg, is_min_val;
350 BtorBitVector *tmp;
351 char *bits;
352 uint32_t size_bits;
353
354 is_min_val = false;
355 is_neg = (str[0] == '-');
356 bits = btor_util_dec_to_bin_str (mm, is_neg ? str + 1 : str);
357 size_bits = strlen (bits);
358 if (is_neg)
359 {
360 is_min_val = (bits[0] == '1');
361 for (size_t i = 1; is_min_val && i < size_bits; i++)
362 is_min_val = (bits[i] == '0');
363 }
364 assert (((is_neg && !is_min_val) || size_bits <= bw)
365 && (!is_neg || is_min_val || size_bits + 1 <= bw));
366
367 res = btor_bv_char_to_bv (mm, bits);
368 btor_mem_freestr (mm, bits);
369 assert (res->width == size_bits);
370 /* zero-extend to bw */
371 if (size_bits < bw)
372 {
373 tmp = btor_bv_uext (mm, res, bw - size_bits);
374 btor_bv_free (mm, res);
375 res = tmp;
376 }
377 if (is_neg)
378 {
379 tmp = btor_bv_neg (mm, res);
380 btor_bv_free (mm, res);
381 res = tmp;
382 }
383 #endif
384 return res;
385 }
386
387 BtorBitVector *
btor_bv_consth(BtorMemMgr * mm,const char * str,uint32_t bw)388 btor_bv_consth (BtorMemMgr *mm, const char *str, uint32_t bw)
389 {
390 assert (btor_util_check_hex_to_bv (mm, str, bw));
391
392 BtorBitVector *res;
393
394 #ifdef BTOR_USE_GMP
395 BTOR_NEW (mm, res);
396 res->width = bw;
397 mpz_init_set_str (res->val, str, 16);
398 #else
399 BtorBitVector *tmp;
400 char *bits;
401 uint32_t size_bits;
402
403 bits = btor_util_hex_to_bin_str (mm, str);
404 size_bits = strlen (bits);
405 assert (size_bits <= bw);
406 res = btor_bv_char_to_bv (mm, bits);
407 btor_mem_freestr (mm, bits);
408 assert (res->width == size_bits);
409 /* zero-extend to bw */
410 if (size_bits < bw)
411 {
412 tmp = btor_bv_uext (mm, res, bw - size_bits);
413 btor_bv_free (mm, res);
414 res = tmp;
415 }
416 #endif
417 return res;
418 }
419
420 /*------------------------------------------------------------------------*/
421
422 BtorBitVector *
btor_bv_get_assignment(BtorMemMgr * mm,BtorNode * exp)423 btor_bv_get_assignment (BtorMemMgr *mm, BtorNode *exp)
424 {
425 assert (mm);
426 assert (exp);
427 assert (!btor_node_is_proxy (exp));
428
429 BtorBitVector *res;
430
431 uint32_t i, j, width;
432 int32_t bit;
433 bool inv;
434 BtorNode *real_exp;
435 BtorAIGVec *av;
436 BtorAIGMgr *amgr;
437
438 exp = btor_node_get_simplified (btor_node_real_addr (exp)->btor, exp);
439 real_exp = btor_node_real_addr (exp);
440
441 if (!real_exp->av)
442 return btor_bv_new (mm, btor_node_bv_get_width (real_exp->btor, real_exp));
443
444 amgr = btor_get_aig_mgr (real_exp->btor);
445 av = real_exp->av;
446 width = av->width;
447 res = btor_bv_new (mm, width);
448 inv = btor_node_is_inverted (exp);
449
450 for (i = 0, j = width - 1; i < width; i++, j--)
451 {
452 bit = btor_aig_get_assignment (amgr, av->aigs[j]);
453 if (inv) bit *= -1;
454 assert (bit == -1 || bit == 1);
455 btor_bv_set_bit (res, i, bit == 1 ? 1 : 0);
456 }
457 return res;
458 }
459
460 /*------------------------------------------------------------------------*/
461
462 BtorBitVector *
btor_bv_copy(BtorMemMgr * mm,const BtorBitVector * bv)463 btor_bv_copy (BtorMemMgr *mm, const BtorBitVector *bv)
464 {
465 assert (mm);
466 assert (bv);
467
468 BtorBitVector *res;
469
470 res = btor_bv_new (mm, bv->width);
471 assert (res->width == bv->width);
472 #ifdef BTOR_USE_GMP
473 mpz_set (res->val, bv->val);
474 #else
475 assert (res->len == bv->len);
476 memcpy (res->bits, bv->bits, sizeof (*(bv->bits)) * bv->len);
477 #endif
478 assert (btor_bv_compare (res, (BtorBitVector *) bv) == 0);
479 return res;
480 }
481
482 /*------------------------------------------------------------------------*/
483
484 size_t
btor_bv_size(const BtorBitVector * bv)485 btor_bv_size (const BtorBitVector *bv)
486 {
487 assert (bv);
488 (void) bv;
489 size_t res;
490 #ifdef BTOR_USE_GMP
491 res = sizeof (BtorBitVector);
492 #else
493 res = sizeof (BtorBitVector) + bv->len * sizeof (BTOR_BV_TYPE);
494 #endif
495 return res;
496 }
497
498 void
btor_bv_free(BtorMemMgr * mm,BtorBitVector * bv)499 btor_bv_free (BtorMemMgr *mm, BtorBitVector *bv)
500 {
501 assert (mm);
502 assert (bv);
503 #ifdef BTOR_USE_GMP
504 mpz_clear (bv->val);
505 btor_mem_free (mm, bv, sizeof (BtorBitVector));
506 #else
507 btor_mem_free (
508 mm, bv, sizeof (BtorBitVector) + sizeof (BTOR_BV_TYPE) * bv->len);
509 #endif
510 }
511
512 int32_t
btor_bv_compare(const BtorBitVector * a,const BtorBitVector * b)513 btor_bv_compare (const BtorBitVector *a, const BtorBitVector *b)
514 {
515 assert (a);
516 assert (b);
517
518 if (a->width != b->width) return -1;
519 #ifdef BTOR_USE_GMP
520 return mpz_cmp (a->val, b->val);
521 #else
522 uint32_t i;
523 /* find index on which a and b differ */
524 for (i = 0; i < a->len && a->bits[i] == b->bits[i]; i++)
525 ;
526 if (i == a->len) return 0;
527 if (a->bits[i] > b->bits[i]) return 1;
528 assert (a->bits[i] < b->bits[i]);
529 return -1;
530 #endif
531 }
532
533 static uint32_t hash_primes[] = {333444569u, 76891121u, 456790003u};
534
535 #define NPRIMES ((uint32_t) (sizeof hash_primes / sizeof *hash_primes))
536
537 uint32_t
btor_bv_hash(const BtorBitVector * bv)538 btor_bv_hash (const BtorBitVector *bv)
539 {
540 assert (bv);
541
542 uint32_t i, j = 0, n, res = 0;
543 uint32_t x, p0, p1;
544
545 res = bv->width * hash_primes[j++];
546
547 #ifdef BTOR_USE_GMP
548 // least significant limb is at index 0
549 mp_limb_t limb;
550 for (i = 0, j = 0, n = mpz_size (bv->val); i < n; ++i)
551 {
552 p0 = hash_primes[j++];
553 if (j == NPRIMES) j = 0;
554 p1 = hash_primes[j++];
555 if (j == NPRIMES) j = 0;
556 limb = mpz_getlimbn (bv->val, i);
557 if (mp_bits_per_limb == 64)
558 {
559 uint32_t lo = (uint32_t) limb;
560 uint32_t hi = (uint32_t) (limb >> 32);
561 x = lo ^ res;
562 x = ((x >> 16) ^ x) * p0;
563 x = ((x >> 16) ^ x) * p1;
564 x = ((x >> 16) ^ x);
565 p0 = hash_primes[j++];
566 if (j == NPRIMES) j = 0;
567 p1 = hash_primes[j++];
568 if (j == NPRIMES) j = 0;
569 x = x ^ hi;
570 }
571 else
572 {
573 assert (mp_bits_per_limb == 32);
574 x = res ^ limb;
575 }
576 x = ((x >> 16) ^ x) * p0;
577 x = ((x >> 16) ^ x) * p1;
578 res = ((x >> 16) ^ x);
579 }
580 #else
581 for (i = 0, j = 0, n = bv->len; i < n; i++)
582 {
583 p0 = hash_primes[j++];
584 if (j == NPRIMES) j = 0;
585 p1 = hash_primes[j++];
586 if (j == NPRIMES) j = 0;
587 x = bv->bits[i] ^ res;
588 x = ((x >> 16) ^ x) * p0;
589 x = ((x >> 16) ^ x) * p1;
590 res = ((x >> 16) ^ x);
591 }
592 #endif
593 return res;
594 }
595
596 /*------------------------------------------------------------------------*/
597
598 void
btor_bv_print_without_new_line(const BtorBitVector * bv)599 btor_bv_print_without_new_line (const BtorBitVector *bv)
600 {
601 assert (bv);
602
603 int64_t i;
604 for (i = bv->width - 1; i >= 0; i--) printf ("%d", btor_bv_get_bit (bv, i));
605 }
606
607 void
btor_bv_print(const BtorBitVector * bv)608 btor_bv_print (const BtorBitVector *bv)
609 {
610 btor_bv_print_without_new_line (bv);
611 printf ("\n");
612 }
613
614 void
btor_bv_print_all(const BtorBitVector * bv)615 btor_bv_print_all (const BtorBitVector *bv)
616 {
617 assert (bv);
618 (void) bv;
619
620 #ifndef BTOR_USE_GMP
621 int64_t i;
622 for (i = BTOR_BV_TYPE_BW * bv->len - 1; i >= 0; i--)
623 {
624 if ((uint32_t) i == (BTOR_BV_TYPE_BW * bv->len + 1 - bv->width))
625 printf ("|");
626 if (i > 0 && (BTOR_BV_TYPE_BW * bv->len - 1 - i) % BTOR_BV_TYPE_BW == 0)
627 printf (".");
628 printf ("%d", btor_bv_get_bit (bv, i));
629 }
630 printf ("\n");
631 #endif
632 }
633
634 /*------------------------------------------------------------------------*/
635
636 char *
btor_bv_to_char(BtorMemMgr * mm,const BtorBitVector * bv)637 btor_bv_to_char (BtorMemMgr *mm, const BtorBitVector *bv)
638 {
639 assert (mm);
640 assert (bv);
641
642 char *res;
643 uint64_t bw = bv->width;
644
645 BTOR_CNEWN (mm, res, bw + 1);
646 #ifdef BTOR_USE_GMP
647 char *tmp = mpz_get_str (0, 2, bv->val);
648 uint64_t n = strlen (tmp);
649 uint64_t diff = bw - n;
650 assert (n <= bw);
651 memset (res, '0', diff);
652 memcpy (res + diff, tmp, n);
653 assert (strlen (res) == bw);
654 free (tmp);
655 #else
656 uint64_t i;
657 uint32_t bit;
658
659 for (i = 0; i < bw; i++)
660 {
661 bit = btor_bv_get_bit (bv, i);
662 res[bw - 1 - i] = bit ? '1' : '0';
663 }
664 res[bw] = '\0';
665 #endif
666 return res;
667 }
668
669 char *
btor_bv_to_hex_char(BtorMemMgr * mm,const BtorBitVector * bv)670 btor_bv_to_hex_char (BtorMemMgr *mm, const BtorBitVector *bv)
671 {
672 assert (mm);
673 assert (bv);
674
675 char *res;
676 uint32_t len;
677
678 len = (bv->width + 3) / 4;
679 BTOR_CNEWN (mm, res, len + 1);
680
681 #ifdef BTOR_USE_GMP
682 char *tmp = mpz_get_str (0, 16, bv->val);
683 uint32_t n = strlen (tmp);
684 uint32_t diff = len - n;
685 assert (n <= len);
686 memset (res, '0', diff);
687 memcpy (res + diff, tmp, n);
688 assert (strlen (res) == len);
689 free (tmp);
690 #else
691 uint32_t i, j, k, tmp;
692 char ch;
693
694 for (i = 0, j = len - 1; i < bv->width;)
695 {
696 tmp = btor_bv_get_bit (bv, i++);
697 for (k = 1; i < bv->width && k <= 3; i++, k++)
698 tmp |= btor_bv_get_bit (bv, i) << k;
699 ch = tmp < 10 ? '0' + tmp : 'a' + (tmp - 10);
700 res[j--] = ch;
701 }
702 #endif
703 return res;
704 }
705
706 static uint32_t
get_first_one_bit_idx(const BtorBitVector * bv)707 get_first_one_bit_idx (const BtorBitVector *bv)
708 {
709 assert (bv);
710
711 #ifdef BTOR_USE_GMP
712 return mpz_scan1 (bv->val, 0);
713 #else
714 uint32_t i;
715 for (i = bv->width - 1; i < UINT32_MAX; i--)
716 {
717 if (btor_bv_get_bit (bv, i)) break;
718 if (i == 0) return UINT32_MAX;
719 }
720 return i;
721 #endif
722 }
723
724 #ifdef BTOR_USE_GMP
725 static uint32_t
get_first_zero_bit_idx(const BtorBitVector * bv)726 get_first_zero_bit_idx (const BtorBitVector *bv)
727 {
728 assert (bv);
729
730 #ifdef BTOR_USE_GMP
731 return mpz_scan0 (bv->val, 0);
732 #else
733 uint32_t i;
734 for (i = bv->width - 1; i < UINT32_MAX; i--)
735 {
736 if (!btor_bv_get_bit (bv, i)) break;
737 if (i == 0) return UINT32_MAX;
738 }
739 return i;
740 #endif
741 }
742 #endif
743
744 char *
btor_bv_to_dec_char(BtorMemMgr * mm,const BtorBitVector * bv)745 btor_bv_to_dec_char (BtorMemMgr *mm, const BtorBitVector *bv)
746 {
747 assert (mm);
748 assert (bv);
749
750 char *res;
751
752 #ifdef BTOR_USE_GMP
753 char *tmp = mpz_get_str (0, 10, bv->val);
754 res = btor_mem_strdup (mm, tmp);
755 free (tmp);
756 #else
757 BtorBitVector *tmp, *div, *rem, *ten;
758 uint32_t i;
759 char ch, *p, *q;
760 BtorCharStack stack;
761
762 if (btor_bv_is_zero (bv))
763 {
764 BTOR_CNEWN (mm, res, 2);
765 res[0] = '0';
766 return res;
767 }
768
769 BTOR_INIT_STACK (mm, stack);
770
771 if (bv->width < 4)
772 {
773 ten = btor_bv_uint64_to_bv (mm, 10, 4);
774 tmp = btor_bv_uext (mm, (BtorBitVector *) bv, 4 - bv->width);
775 }
776 else
777 {
778 ten = btor_bv_uint64_to_bv (mm, 10, bv->width);
779 tmp = btor_bv_copy (mm, bv);
780 }
781 while (!btor_bv_is_zero (tmp))
782 {
783 div = btor_bv_udiv (mm, tmp, ten);
784 rem = btor_bv_urem (mm, tmp, ten);
785 ch = 0;
786 for (i = get_first_one_bit_idx (rem); i < UINT32_MAX; i--)
787 {
788 ch <<= 1;
789 if (btor_bv_get_bit (rem, i)) ch += 1;
790 }
791 assert (ch < 10);
792 ch += '0';
793 BTOR_PUSH_STACK (stack, ch);
794 btor_bv_free (mm, rem);
795 btor_bv_free (mm, tmp);
796 tmp = div;
797 }
798 btor_bv_free (mm, tmp);
799 btor_bv_free (mm, ten);
800 if (BTOR_EMPTY_STACK (stack)) BTOR_PUSH_STACK (stack, '0');
801 BTOR_NEWN (mm, res, BTOR_COUNT_STACK (stack) + 1);
802 q = res;
803 p = stack.top;
804 while (p > stack.start) *q++ = *--p;
805 assert (res + BTOR_COUNT_STACK (stack) == q);
806 *q = 0;
807 assert ((uint32_t) BTOR_COUNT_STACK (stack) == strlen (res));
808 BTOR_RELEASE_STACK (stack);
809 #endif
810 return res;
811 }
812
813 /*------------------------------------------------------------------------*/
814
815 uint64_t
btor_bv_to_uint64(const BtorBitVector * bv)816 btor_bv_to_uint64 (const BtorBitVector *bv)
817 {
818 assert (bv);
819 assert (bv->width <= sizeof (uint64_t) * 8);
820
821 uint64_t res;
822
823 #ifdef BTOR_USE_GMP
824 res = mpz_get_ui (bv->val);
825 #else
826 assert (bv->len <= 2);
827 uint32_t i;
828 res = 0;
829 for (i = 0; i < bv->len; i++)
830 res |= ((uint64_t) bv->bits[i]) << (BTOR_BV_TYPE_BW * (bv->len - 1 - i));
831 #endif
832
833 return res;
834 }
835
836 /*------------------------------------------------------------------------*/
837
838 uint32_t
btor_bv_get_width(const BtorBitVector * bv)839 btor_bv_get_width (const BtorBitVector *bv)
840 {
841 assert (bv);
842 return bv->width;
843 }
844
845 uint32_t
btor_bv_get_len(const BtorBitVector * bv)846 btor_bv_get_len (const BtorBitVector *bv)
847 {
848 assert (bv);
849 (void) bv;
850 #ifdef BTOR_USE_GMP
851 return 0;
852 #else
853 return bv->len;
854 #endif
855 }
856
857 uint32_t
btor_bv_get_bit(const BtorBitVector * bv,uint32_t pos)858 btor_bv_get_bit (const BtorBitVector *bv, uint32_t pos)
859 {
860 assert (bv);
861 assert (pos < bv->width);
862
863 #ifdef BTOR_USE_GMP
864 return mpz_tstbit (bv->val, pos);
865 #else
866 uint32_t i, j;
867
868 i = pos / BTOR_BV_TYPE_BW;
869 j = pos % BTOR_BV_TYPE_BW;
870
871 return (bv->bits[bv->len - 1 - i] >> j) & 1;
872 #endif
873 }
874
875 void
btor_bv_set_bit(BtorBitVector * bv,uint32_t pos,uint32_t bit)876 btor_bv_set_bit (BtorBitVector *bv, uint32_t pos, uint32_t bit)
877 {
878 assert (bv);
879 assert (bit == 0 || bit == 1);
880 assert (pos < bv->width);
881
882 #ifdef BTOR_USE_GMP
883 if (bit)
884 {
885 mpz_setbit (bv->val, pos);
886 }
887 else
888 {
889 mpz_clrbit (bv->val, pos);
890 }
891 #else
892 assert (bv->len > 0);
893 uint32_t i, j;
894
895 i = pos / BTOR_BV_TYPE_BW;
896 j = pos % BTOR_BV_TYPE_BW;
897 assert (i < bv->len);
898
899 if (bit)
900 {
901 bv->bits[bv->len - 1 - i] |= (1u << j);
902 }
903 else
904 {
905 bv->bits[bv->len - 1 - i] &= ~(1u << j);
906 }
907 #endif
908 }
909
910 void
btor_bv_flip_bit(BtorBitVector * bv,uint32_t pos)911 btor_bv_flip_bit (BtorBitVector *bv, uint32_t pos)
912 {
913 assert (bv);
914 assert (pos < bv->width);
915
916 #ifdef BTOR_USE_GMP
917 mpz_combit (bv->val, pos);
918 #else
919 assert (bv->len > 0);
920 btor_bv_set_bit (bv, pos, btor_bv_get_bit (bv, pos) ? 0 : 1);
921 #endif
922 }
923
924 /*------------------------------------------------------------------------*/
925
926 bool
btor_bv_is_true(const BtorBitVector * bv)927 btor_bv_is_true (const BtorBitVector *bv)
928 {
929 assert (bv);
930
931 if (bv->width != 1) return 0;
932 return btor_bv_get_bit (bv, 0);
933 }
934
935 bool
btor_bv_is_false(const BtorBitVector * bv)936 btor_bv_is_false (const BtorBitVector *bv)
937 {
938 assert (bv);
939
940 if (bv->width != 1) return 0;
941 return !btor_bv_get_bit (bv, 0);
942 }
943
944 bool
btor_bv_is_zero(const BtorBitVector * bv)945 btor_bv_is_zero (const BtorBitVector *bv)
946 {
947 assert (bv);
948
949 #ifdef BTOR_USE_GMP
950 return mpz_cmp_ui (bv->val, 0) == 0;
951 #else
952 uint32_t i;
953 for (i = 0; i < bv->len; i++)
954 if (bv->bits[i] != 0) return false;
955 return true;
956 #endif
957 }
958
959 bool
btor_bv_is_ones(const BtorBitVector * bv)960 btor_bv_is_ones (const BtorBitVector *bv)
961 {
962 assert (bv);
963
964 uint32_t i, n;
965 #ifdef BTOR_USE_GMP
966 uint64_t m, max;
967 mp_limb_t limb;
968 if ((n = mpz_size (bv->val)) == 0) return false; // zero
969 m = bv->width / mp_bits_per_limb;
970 if (bv->width % mp_bits_per_limb) m += 1;
971 if (m != n) return false; // less limbs used than expected, not ones
972 max = mp_bits_per_limb == 64 ? UINT64_MAX : UINT32_MAX;
973 for (i = 0; i < n - 1; i++)
974 {
975 limb = mpz_getlimbn (bv->val, i);
976 if (((uint64_t) limb) != max) return false;
977 }
978 limb = mpz_getlimbn (bv->val, n - 1);
979 if (bv->width == (uint32_t) mp_bits_per_limb)
980 return ((uint64_t) limb) == max;
981 m = mp_bits_per_limb - bv->width % mp_bits_per_limb;
982 return ((uint64_t) limb) == (max >> m);
983 #else
984 for (i = bv->len - 1; i >= 1; i--)
985 {
986 if (bv->bits[i] != UINT32_MAX) return false;
987 }
988 n = BTOR_BV_TYPE_BW - bv->width % BTOR_BV_TYPE_BW;
989 assert (n > 0);
990 if (n == BTOR_BV_TYPE_BW) return bv->bits[0] == UINT32_MAX;
991 return bv->bits[0] == (UINT32_MAX >> n);
992 #endif
993 }
994
995 bool
btor_bv_is_one(const BtorBitVector * bv)996 btor_bv_is_one (const BtorBitVector *bv)
997 {
998 assert (bv);
999
1000 #ifdef BTOR_USE_GMP
1001 return mpz_cmp_ui (bv->val, 1) == 0;
1002 #else
1003 uint32_t i;
1004 if (bv->bits[bv->len - 1] != 1) return false;
1005 for (i = 0; i < bv->len - 1; i++)
1006 if (bv->bits[i] != 0) return false;
1007 return true;
1008 #endif
1009 }
1010
1011 bool
btor_bv_is_min_signed(const BtorBitVector * bv)1012 btor_bv_is_min_signed (const BtorBitVector *bv)
1013 {
1014 assert (bv);
1015
1016 #ifdef BTOR_USE_GMP
1017 if (get_first_one_bit_idx (bv) != bv->width - 1) return false;
1018 #else
1019 uint32_t i;
1020 if (bv->bits[0] != (1u << ((bv->width % BTOR_BV_TYPE_BW) - 1))) return false;
1021 for (i = 1; i < bv->len; i++)
1022 if (bv->bits[i] != 0) return false;
1023 #endif
1024 return true;
1025 }
1026
1027 bool
btor_bv_is_max_signed(const BtorBitVector * bv)1028 btor_bv_is_max_signed (const BtorBitVector *bv)
1029 {
1030 assert (bv);
1031
1032 #ifdef BTOR_USE_GMP
1033 if (get_first_zero_bit_idx (bv) != bv->width - 1) return false;
1034 #else
1035 uint32_t i, msc;
1036
1037 msc = (BTOR_BV_TYPE_BW - (bv->width % BTOR_BV_TYPE_BW) + 1);
1038 if (msc == BTOR_BV_TYPE_BW)
1039 {
1040 if (bv->bits[0] != 0) return false;
1041 }
1042 else if (bv->bits[0] != (~0u >> msc))
1043 {
1044 return false;
1045 }
1046 for (i = 1; i < bv->len; i++)
1047 if (bv->bits[i] != ~0u) return false;
1048 #endif
1049 return true;
1050 }
1051
1052 int64_t
btor_bv_power_of_two(const BtorBitVector * bv)1053 btor_bv_power_of_two (const BtorBitVector *bv)
1054 {
1055 assert (bv);
1056
1057 int64_t i, j;
1058 uint32_t bit;
1059 bool iszero;
1060
1061 for (i = 0, j = 0, iszero = true; i < bv->width; i++)
1062 {
1063 bit = btor_bv_get_bit (bv, i);
1064 if (!bit) continue;
1065 if (bit && !iszero) return -1;
1066 assert (bit && iszero);
1067 j = i;
1068 iszero = false;
1069 }
1070 return j;
1071 }
1072
1073 int32_t
btor_bv_small_positive_int(const BtorBitVector * bv)1074 btor_bv_small_positive_int (const BtorBitVector *bv)
1075 {
1076 assert (bv);
1077
1078 int32_t res;
1079 uint32_t i, n;
1080 #ifdef BTOR_USE_GMP
1081 if (!(n = mpz_size (bv->val))) return 0;
1082 mp_limb_t limb;
1083 for (i = 0; i < n; i++)
1084 {
1085 limb = mpz_getlimbn (bv->val, i);
1086 if (i == n - 1)
1087 {
1088 if (mp_bits_per_limb == 64)
1089 {
1090 if (limb >> 32 != 0)
1091 {
1092 return -1;
1093 }
1094 }
1095 }
1096 else
1097 {
1098 if (limb != 0)
1099 {
1100 return -1;
1101 }
1102 }
1103 }
1104 res = (int32_t) limb;
1105 if (res < 0) return -1;
1106 #else
1107 for (i = 0, n = bv->len - 1; i < n; i++)
1108 if (bv->bits[i] != 0) return -1;
1109 if (((int32_t) bv->bits[bv->len - 1]) < 0) return -1;
1110 res = bv->bits[bv->len - 1];
1111 #endif
1112 return res;
1113 }
1114
1115 uint32_t
btor_bv_get_num_trailing_zeros(const BtorBitVector * bv)1116 btor_bv_get_num_trailing_zeros (const BtorBitVector *bv)
1117 {
1118 assert (bv);
1119
1120 uint32_t res = 0;
1121 #ifdef BTOR_USE_GMP
1122 res = mpz_scan1(bv->val, 0);
1123 if (res > bv->width) res = bv->width;
1124 #else
1125 uint32_t i;
1126
1127 for (i = 0, res = 0; i < bv->width; i++)
1128 {
1129 if (btor_bv_get_bit (bv, i)) break;
1130 res += 1;
1131 }
1132 #endif
1133 return res;
1134 }
1135
1136 /**
1137 * Get the first limb and return the number of limbs needed to represented
1138 * given bit-vector if all zero limbs are disregarded.
1139 */
1140 #ifdef BTOR_USE_GMP
1141 static uint32_t
get_limb(const BtorBitVector * bv,mp_limb_t * limb,uint32_t nbits_rem,bool zeros)1142 get_limb (const BtorBitVector *bv,
1143 mp_limb_t *limb,
1144 uint32_t nbits_rem,
1145 bool zeros)
1146 {
1147 /* GMP normalizes the limbs, the left most (most significant) is never 0 */
1148 uint32_t i, n_limbs, n_limbs_total;
1149 mp_limb_t res = 0u, mask;
1150
1151 n_limbs = mpz_size (bv->val);
1152
1153 /* for leading zeros */
1154 if (zeros)
1155 {
1156 *limb = n_limbs ? mpz_getlimbn (bv->val, n_limbs - 1) : 0;
1157 return n_limbs;
1158 }
1159
1160 /* for leading ones */
1161 n_limbs_total = bv->width / mp_bits_per_limb + (nbits_rem ? 1 : 0);
1162 if (n_limbs != n_limbs_total)
1163 {
1164 /* no leading ones, simulate */
1165 *limb = nbits_rem ? ~(~((mp_limb_t) 0) << nbits_rem) : ~((mp_limb_t) 0);
1166 return n_limbs_total;
1167 }
1168 mask = ~((mp_limb_t) 0) << nbits_rem;
1169 for (i = 0; i < n_limbs; i++)
1170 {
1171 res = mpz_getlimbn (bv->val, n_limbs - 1 - i);
1172 if (nbits_rem && i == 0)
1173 {
1174 res = res | mask;
1175 }
1176 res = ~res;
1177 if (res > 0) break;
1178 }
1179 *limb = res;
1180 return n_limbs - i;
1181 }
1182 #else
1183 static uint32_t
get_limb(const BtorBitVector * bv,BTOR_BV_TYPE * limb,uint32_t nbits_rem,bool zeros)1184 get_limb (const BtorBitVector *bv,
1185 BTOR_BV_TYPE *limb,
1186 uint32_t nbits_rem,
1187 bool zeros)
1188 {
1189 uint32_t i;
1190 BTOR_BV_TYPE res = 0u, mask;
1191
1192 /* for leading zeros */
1193 if (zeros)
1194 {
1195 for (i = 0; i < bv->len; i++)
1196 {
1197 res = bv->bits[i];
1198 if (res > 0) break;
1199 }
1200 }
1201 /* for leading ones */
1202 else
1203 {
1204 mask = ~((BTOR_BV_TYPE) 0) << nbits_rem;
1205 for (i = 0; i < bv->len; i++)
1206 {
1207 res = bv->bits[i];
1208 if (nbits_rem && i == 0)
1209 {
1210 res = res | mask;
1211 }
1212 res = ~res;
1213 if (res > 0) break;
1214 }
1215 }
1216
1217 *limb = res;
1218 return bv->len - i;
1219 }
1220 #endif
1221
1222 #if !defined(__GNUC__) && !defined(__clang__)
1223 static uint32_t
1224 #ifdef BTOR_USE_GMP
clz_limb(uint32_t nbits_per_limb,mp_limb_t limb)1225 clz_limb (uint32_t nbits_per_limb, mp_limb_t limb)
1226 #else
1227 clz_limb (uint32_t nbits_per_limb, BTOR_BV_TYPE limb)
1228 #endif
1229 {
1230 uint32_t w;
1231 #ifdef BTOR_USE_GMP
1232 mp_limb_t mask;
1233 mp_limb_t one = 1u;
1234 #else
1235 BTOR_BV_TYPE mask;
1236 BTOR_BV_TYPE one = 1u;
1237 #endif
1238 for (w = 0, mask = 0; w < nbits_per_limb; w++)
1239 {
1240 mask += (one << w);
1241 if ((limb & ~mask) == 0) break;
1242 }
1243 return nbits_per_limb - 1 - w;
1244 }
1245 #endif
1246
1247 static uint32_t
get_num_leading(const BtorBitVector * bv,bool zeros)1248 get_num_leading (const BtorBitVector *bv, bool zeros)
1249 {
1250 assert (bv);
1251
1252 uint32_t res = 0, nbits_pad;
1253 /* The number of limbs required to represent the actual value.
1254 * Zero limbs are disregarded. */
1255 uint32_t n_limbs;
1256 /* Number of limbs required when representing all bits. */
1257 uint32_t n_limbs_total;
1258 /* The number of bits that spill over into the most significant limb,
1259 * assuming that all bits are represented). Zero if the bit-width is a
1260 * multiple of n_bits_per_limb. */
1261 uint32_t nbits_rem;
1262 uint32_t nbits_per_limb;
1263 #ifdef BTOR_USE_GMP
1264 mp_limb_t limb;
1265 #else
1266 BTOR_BV_TYPE limb;
1267 #endif
1268
1269 #ifdef BTOR_USE_GMP
1270 nbits_per_limb = mp_bits_per_limb;
1271 #else
1272 nbits_per_limb = BTOR_BV_TYPE_BW;
1273 #endif
1274
1275 nbits_rem = bv->width % nbits_per_limb;
1276
1277 n_limbs = get_limb (bv, &limb, nbits_rem, zeros);
1278 if (n_limbs == 0) return bv->width;
1279
1280 #if defined(__GNUC__) || defined(__clang__)
1281 res = nbits_per_limb == 64 ? __builtin_clzll (limb) : __builtin_clz (limb);
1282 #else
1283 res = clz_limb (nbits_per_limb, limb);
1284 #endif
1285 n_limbs_total = bv->width / nbits_per_limb + 1;
1286 nbits_pad = nbits_per_limb - nbits_rem;
1287 res += (n_limbs_total - n_limbs) * nbits_per_limb - nbits_pad;
1288 return res;
1289 }
1290
1291 uint32_t
btor_bv_get_num_leading_zeros(const BtorBitVector * bv)1292 btor_bv_get_num_leading_zeros (const BtorBitVector *bv)
1293 {
1294 return get_num_leading (bv, true);
1295 }
1296
1297 uint32_t
btor_bv_get_num_leading_ones(const BtorBitVector * bv)1298 btor_bv_get_num_leading_ones (const BtorBitVector *bv)
1299 {
1300 assert (bv);
1301
1302 return get_num_leading (bv, false);
1303 #if 0
1304 uint32_t res = 0;
1305 uint32_t i;
1306
1307 for (i = bv->width - 1, res = 0; i < UINT32_MAX; i--)
1308 {
1309 if (!btor_bv_get_bit (bv, i)) break;
1310 res += 1;
1311 }
1312 return res;
1313 #endif
1314 }
1315
1316 /*------------------------------------------------------------------------*/
1317
1318 BtorBitVector *
btor_bv_one(BtorMemMgr * mm,uint32_t bw)1319 btor_bv_one (BtorMemMgr *mm, uint32_t bw)
1320 {
1321 assert (mm);
1322 assert (bw);
1323
1324 BtorBitVector *res;
1325 #ifdef BTOR_USE_GMP
1326 BTOR_NEW (mm, res);
1327 res->width = bw;
1328 mpz_init_set_ui (res->val, 1);
1329 #else
1330 res = btor_bv_new (mm, bw);
1331 btor_bv_set_bit (res, 0, 1);
1332 #endif
1333 return res;
1334 }
1335
1336 BtorBitVector *
btor_bv_ones(BtorMemMgr * mm,uint32_t bw)1337 btor_bv_ones (BtorMemMgr *mm, uint32_t bw)
1338 {
1339 assert (mm);
1340 assert (bw);
1341
1342 BtorBitVector *res;
1343 #ifdef BTOR_USE_GMP
1344 res = btor_bv_one (mm, bw);
1345 mpz_mul_2exp (res->val, res->val, bw);
1346 mpz_sub_ui (res->val, res->val, 1);
1347 #else
1348 BtorBitVector *tmp;
1349 tmp = btor_bv_new (mm, bw);
1350 res = btor_bv_not (mm, tmp);
1351 btor_bv_free (mm, tmp);
1352 #endif
1353 return res;
1354 }
1355
1356 BtorBitVector *
btor_bv_min_signed(BtorMemMgr * mm,uint32_t bw)1357 btor_bv_min_signed (BtorMemMgr *mm, uint32_t bw)
1358 {
1359 assert (mm);
1360 assert (bw);
1361
1362 BtorBitVector *res;
1363 res = btor_bv_new (mm, bw);
1364 #ifdef BTOR_USE_GMP
1365 mpz_setbit (res->val, bw - 1);
1366 #else
1367 btor_bv_set_bit (res, bw - 1, 1);
1368 #endif
1369 return res;
1370 }
1371
1372 BtorBitVector *
btor_bv_max_signed(BtorMemMgr * mm,uint32_t bw)1373 btor_bv_max_signed (BtorMemMgr *mm, uint32_t bw)
1374 {
1375 assert (mm);
1376 assert (bw);
1377
1378 BtorBitVector *res;
1379 res = btor_bv_ones (mm, bw);
1380 btor_bv_set_bit (res, bw - 1, 0);
1381 return res;
1382 }
1383
1384 BtorBitVector *
btor_bv_neg(BtorMemMgr * mm,const BtorBitVector * bv)1385 btor_bv_neg (BtorMemMgr *mm, const BtorBitVector *bv)
1386 {
1387 assert (mm);
1388 assert (bv);
1389
1390 BtorBitVector *res;
1391 uint32_t bw = bv->width;
1392 #ifdef BTOR_USE_GMP
1393 res = btor_bv_not (mm, bv);
1394 mpz_add_ui (res->val, res->val, 1);
1395 mpz_fdiv_r_2exp (res->val, res->val, bw);
1396 #else
1397 BtorBitVector *not_bv, *one;
1398 not_bv = btor_bv_not (mm, bv);
1399 one = btor_bv_uint64_to_bv (mm, 1, bw);
1400 res = btor_bv_add (mm, not_bv, one);
1401 btor_bv_free (mm, not_bv);
1402 btor_bv_free (mm, one);
1403 #endif
1404 return res;
1405 }
1406
1407 BtorBitVector *
btor_bv_not(BtorMemMgr * mm,const BtorBitVector * bv)1408 btor_bv_not (BtorMemMgr *mm, const BtorBitVector *bv)
1409 {
1410 assert (mm);
1411 assert (bv);
1412
1413 BtorBitVector *res;
1414 uint32_t bw = bv->width;
1415 #ifdef BTOR_USE_GMP
1416 res = btor_bv_new (mm, bw);
1417 mpz_com (res->val, bv->val);
1418 mpz_fdiv_r_2exp (res->val, res->val, bw);
1419 #else
1420 uint32_t i;
1421 res = btor_bv_new (mm, bw);
1422 for (i = 0; i < bv->len; i++) res->bits[i] = ~bv->bits[i];
1423 set_rem_bits_to_zero (res);
1424 assert (rem_bits_zero_dbg (res));
1425 #endif
1426 return res;
1427 }
1428
1429 BtorBitVector *
btor_bv_inc(BtorMemMgr * mm,const BtorBitVector * bv)1430 btor_bv_inc (BtorMemMgr *mm, const BtorBitVector *bv)
1431 {
1432 assert (mm);
1433 assert (bv);
1434
1435 BtorBitVector *res;
1436 uint32_t bw = bv->width;
1437 #ifdef BTOR_USE_GMP
1438 res = btor_bv_new (mm, bw);
1439 mpz_add_ui (res->val, bv->val, 1);
1440 mpz_fdiv_r_2exp (res->val, res->val, bw);
1441 #else
1442 BtorBitVector *one;
1443 one = btor_bv_uint64_to_bv (mm, 1, bw);
1444 res = btor_bv_add (mm, bv, one);
1445 btor_bv_free (mm, one);
1446 #endif
1447 return res;
1448 }
1449
1450 BtorBitVector *
btor_bv_dec(BtorMemMgr * mm,const BtorBitVector * bv)1451 btor_bv_dec (BtorMemMgr *mm, const BtorBitVector *bv)
1452 {
1453 assert (mm);
1454 assert (bv);
1455
1456 BtorBitVector *res;
1457 uint32_t bw = bv->width;
1458 #ifdef BTOR_USE_GMP
1459 res = btor_bv_new (mm, bw);
1460 mpz_sub_ui (res->val, bv->val, 1);
1461 mpz_fdiv_r_2exp (res->val, res->val, bw);
1462 #else
1463 BtorBitVector *one, *negone;
1464 one = btor_bv_uint64_to_bv (mm, 1, bw);
1465 negone = btor_bv_neg (mm, one);
1466 res = btor_bv_add (mm, bv, negone);
1467 btor_bv_free (mm, one);
1468 btor_bv_free (mm, negone);
1469 #endif
1470 return res;
1471 }
1472
1473 BtorBitVector *
btor_bv_redand(BtorMemMgr * mm,const BtorBitVector * bv)1474 btor_bv_redand (BtorMemMgr *mm, const BtorBitVector *bv)
1475 {
1476 assert (mm);
1477 assert (bv);
1478
1479 BtorBitVector *res;
1480 #ifdef BTOR_USE_GMP
1481 res = btor_bv_is_ones (bv) ? btor_bv_one (mm, 1) : btor_bv_zero (mm, 1);
1482 #else
1483 uint32_t i;
1484 uint32_t bit;
1485 uint32_t mask0;
1486
1487 res = btor_bv_new (mm, 1);
1488 assert (rem_bits_zero_dbg (res));
1489
1490 if (bv->width == BTOR_BV_TYPE_BW * bv->len)
1491 mask0 = ~(BTOR_BV_TYPE) 0;
1492 else
1493 mask0 = BTOR_MASK_REM_BITS (bv);
1494
1495 bit = (bv->bits[0] == mask0);
1496
1497 for (i = 1; bit && i < bv->len; i++)
1498 if (bv->bits[i] != ~(BTOR_BV_TYPE) 0) bit = 0;
1499
1500 btor_bv_set_bit (res, 0, bit);
1501
1502 assert (rem_bits_zero_dbg (res));
1503 #endif
1504 return res;
1505 }
1506
1507 BtorBitVector *
btor_bv_redor(BtorMemMgr * mm,const BtorBitVector * bv)1508 btor_bv_redor (BtorMemMgr *mm, const BtorBitVector *bv)
1509 {
1510 assert (mm);
1511 assert (bv);
1512
1513 #ifdef BTOR_USE_GMP
1514 mp_limb_t limb;
1515 size_t i, n;
1516 for (i = 0, n = mpz_size (bv->val); i < n; i++)
1517 {
1518 limb = mpz_getlimbn (bv->val, i);
1519 if (((uint64_t) limb) != 0) return btor_bv_one (mm, 1);
1520 }
1521 return btor_bv_zero (mm, 1);
1522 #else
1523 uint32_t i;
1524 uint32_t bit;
1525 BtorBitVector *res;
1526
1527 res = btor_bv_new (mm, 1);
1528 assert (rem_bits_zero_dbg (res));
1529 bit = 0;
1530 for (i = 0; !bit && i < bv->len; i++)
1531 if (bv->bits[i]) bit = 1;
1532
1533 btor_bv_set_bit (res, 0, bit);
1534
1535 assert (rem_bits_zero_dbg (res));
1536 return res;
1537 #endif
1538 }
1539
1540 /*------------------------------------------------------------------------*/
1541
1542 BtorBitVector *
btor_bv_add(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1543 btor_bv_add (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1544 {
1545 assert (mm);
1546 assert (a);
1547 assert (b);
1548 assert (a->width == b->width);
1549
1550 BtorBitVector *res;
1551 uint32_t bw = a->width;
1552 #ifdef BTOR_USE_GMP
1553 res = btor_bv_new (mm, bw);
1554 mpz_add (res->val, a->val, b->val);
1555 mpz_fdiv_r_2exp (res->val, res->val, bw);
1556 #else
1557 assert (a->len == b->len);
1558 int64_t i;
1559 uint64_t x, y, sum;
1560 BTOR_BV_TYPE carry;
1561
1562 if (bw <= 64)
1563 {
1564 x = btor_bv_to_uint64 (a);
1565 y = btor_bv_to_uint64 (b);
1566 res = btor_bv_uint64_to_bv (mm, x + y, bw);
1567 }
1568 else
1569 {
1570 res = btor_bv_new (mm, bw);
1571 carry = 0;
1572 for (i = a->len - 1; i >= 0; i--)
1573 {
1574 sum = (uint64_t) a->bits[i] + b->bits[i] + carry;
1575 res->bits[i] = (BTOR_BV_TYPE) sum;
1576 carry = (BTOR_BV_TYPE) (sum >> 32);
1577 }
1578 }
1579
1580 set_rem_bits_to_zero (res);
1581 assert (rem_bits_zero_dbg (res));
1582 #endif
1583 return res;
1584 }
1585
1586 BtorBitVector *
btor_bv_sub(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1587 btor_bv_sub (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1588 {
1589 assert (mm);
1590 assert (a);
1591 assert (b);
1592 assert (a->width == b->width);
1593
1594 BtorBitVector *res;
1595 #ifdef BTOR_USE_GMP
1596 uint32_t bw = a->width;
1597 res = btor_bv_new (mm, bw);
1598 mpz_sub (res->val, a->val, b->val);
1599 mpz_fdiv_r_2exp (res->val, res->val, bw);
1600 #else
1601 assert (a->len == b->len);
1602 BtorBitVector *negb;
1603
1604 negb = btor_bv_neg (mm, b);
1605 res = btor_bv_add (mm, a, negb);
1606 btor_bv_free (mm, negb);
1607 #endif
1608 return res;
1609 }
1610
1611 BtorBitVector *
btor_bv_and(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1612 btor_bv_and (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1613 {
1614 assert (mm);
1615 assert (a);
1616 assert (b);
1617 assert (a->width == b->width);
1618
1619 BtorBitVector *res;
1620 uint32_t bw = a->width;
1621 #ifdef BTOR_USE_GMP
1622 res = btor_bv_new (mm, bw);
1623 mpz_and (res->val, a->val, b->val);
1624 mpz_fdiv_r_2exp (res->val, res->val, bw);
1625 #else
1626 assert (a->len == b->len);
1627 uint32_t i;
1628
1629 res = btor_bv_new (mm, bw);
1630 for (i = 0; i < a->len; i++) res->bits[i] = a->bits[i] & b->bits[i];
1631
1632 assert (rem_bits_zero_dbg (res));
1633 #endif
1634 return res;
1635 }
1636
1637 BtorBitVector *
btor_bv_implies(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1638 btor_bv_implies (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1639 {
1640 assert (mm);
1641 assert (a);
1642 assert (b);
1643 assert (a->width == b->width);
1644 assert (a->width == 1);
1645
1646 BtorBitVector *res;
1647 #ifdef BTOR_USE_GMP
1648 res = btor_bv_is_zero (a) || btor_bv_is_one (b) ? btor_bv_one (mm, 1)
1649 : btor_bv_zero (mm, 1);
1650 #else
1651 assert (a->len == b->len);
1652 uint32_t i;
1653
1654 res = btor_bv_new (mm, a->width);
1655 for (i = 0; i < a->len; i++) res->bits[i] = ~a->bits[i] | b->bits[i];
1656
1657 set_rem_bits_to_zero (res);
1658 assert (rem_bits_zero_dbg (res));
1659 #endif
1660 return res;
1661 }
1662
1663 BtorBitVector *
btor_bv_or(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1664 btor_bv_or (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1665 {
1666 assert (mm);
1667 assert (a);
1668 assert (b);
1669 assert (a->width == b->width);
1670
1671 BtorBitVector *res;
1672 uint32_t bw = a->width;
1673 #ifdef BTOR_USE_GMP
1674 res = btor_bv_new (mm, bw);
1675 mpz_ior (res->val, a->val, b->val);
1676 mpz_fdiv_r_2exp (res->val, res->val, bw);
1677 #else
1678 assert (a->len == b->len);
1679 uint32_t i;
1680
1681 res = btor_bv_new (mm, bw);
1682 for (i = 0; i < a->len; i++) res->bits[i] = a->bits[i] | b->bits[i];
1683
1684 assert (rem_bits_zero_dbg (res));
1685 #endif
1686 return res;
1687 }
1688
1689 BtorBitVector *
btor_bv_nand(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1690 btor_bv_nand (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1691 {
1692 assert (mm);
1693 assert (a);
1694 assert (b);
1695 assert (a->width == b->width);
1696
1697 BtorBitVector *res;
1698 uint32_t bw = a->width;
1699 #ifdef BTOR_USE_GMP
1700 res = btor_bv_new (mm, bw);
1701 mpz_and (res->val, a->val, b->val);
1702 mpz_com (res->val, res->val);
1703 mpz_fdiv_r_2exp (res->val, res->val, bw);
1704 #else
1705 assert (a->len == b->len);
1706 uint32_t i;
1707
1708 res = btor_bv_new (mm, bw);
1709 for (i = 0; i < a->len; i++) res->bits[i] = ~(a->bits[i] & b->bits[i]);
1710
1711 set_rem_bits_to_zero (res);
1712 assert (rem_bits_zero_dbg (res));
1713 #endif
1714 return res;
1715 }
1716
1717 BtorBitVector *
btor_bv_nor(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1718 btor_bv_nor (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1719 {
1720 assert (mm);
1721 assert (a);
1722 assert (b);
1723 assert (a->width == b->width);
1724
1725 BtorBitVector *res;
1726 uint32_t bw = a->width;
1727 #ifdef BTOR_USE_GMP
1728 res = btor_bv_new (mm, bw);
1729 mpz_ior (res->val, a->val, b->val);
1730 mpz_com (res->val, res->val);
1731 mpz_fdiv_r_2exp (res->val, res->val, bw);
1732 #else
1733 assert (a->len == b->len);
1734 uint32_t i;
1735
1736 res = btor_bv_new (mm, bw);
1737 for (i = 0; i < a->len; i++) res->bits[i] = ~(a->bits[i] | b->bits[i]);
1738
1739 set_rem_bits_to_zero (res);
1740 assert (rem_bits_zero_dbg (res));
1741 #endif
1742 return res;
1743 }
1744
1745 BtorBitVector *
btor_bv_xnor(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1746 btor_bv_xnor (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1747 {
1748 assert (mm);
1749 assert (a);
1750 assert (b);
1751 assert (a->width == b->width);
1752
1753 BtorBitVector *res;
1754 uint32_t bw = a->width;
1755 #ifdef BTOR_USE_GMP
1756 res = btor_bv_new (mm, bw);
1757 mpz_xor (res->val, a->val, b->val);
1758 mpz_com (res->val, res->val);
1759 mpz_fdiv_r_2exp (res->val, res->val, bw);
1760 #else
1761 assert (a->len == b->len);
1762 uint32_t i;
1763
1764 res = btor_bv_new (mm, bw);
1765 for (i = 0; i < a->len; i++) res->bits[i] = a->bits[i] ^ ~b->bits[i];
1766
1767 set_rem_bits_to_zero (res);
1768 assert (rem_bits_zero_dbg (res));
1769 #endif
1770 return res;
1771 }
1772
1773 BtorBitVector *
btor_bv_xor(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1774 btor_bv_xor (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1775 {
1776 assert (mm);
1777 assert (a);
1778 assert (b);
1779 assert (a->width == b->width);
1780
1781 BtorBitVector *res;
1782 uint32_t bw = a->width;
1783 #ifdef BTOR_USE_GMP
1784 res = btor_bv_new (mm, bw);
1785 mpz_xor (res->val, a->val, b->val);
1786 mpz_fdiv_r_2exp (res->val, res->val, bw);
1787 #else
1788 assert (a->len == b->len);
1789 uint32_t i;
1790
1791 res = btor_bv_new (mm, bw);
1792 for (i = 0; i < a->len; i++) res->bits[i] = a->bits[i] ^ b->bits[i];
1793
1794 assert (rem_bits_zero_dbg (res));
1795 #endif
1796 return res;
1797 }
1798
1799 BtorBitVector *
btor_bv_eq(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1800 btor_bv_eq (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1801 {
1802 assert (mm);
1803 assert (a);
1804 assert (b);
1805 assert (a->width == b->width);
1806
1807 BtorBitVector *res;
1808 #ifdef BTOR_USE_GMP
1809 res = mpz_cmp (a->val, b->val) == 0 ? btor_bv_one (mm, 1)
1810 : btor_bv_zero (mm, 1);
1811 #else
1812 assert (a->len == b->len);
1813 uint32_t i, bit;
1814
1815 res = btor_bv_new (mm, 1);
1816 bit = 1;
1817 for (i = 0; i < a->len; i++)
1818 {
1819 if (a->bits[i] != b->bits[i])
1820 {
1821 bit = 0;
1822 break;
1823 }
1824 }
1825 btor_bv_set_bit (res, 0, bit);
1826
1827 assert (rem_bits_zero_dbg (res));
1828 #endif
1829 return res;
1830 }
1831
1832 BtorBitVector *
btor_bv_ne(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1833 btor_bv_ne (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1834 {
1835 assert (mm);
1836 assert (a);
1837 assert (b);
1838 assert (a->width == b->width);
1839
1840 BtorBitVector *res;
1841 #ifdef BTOR_USE_GMP
1842 res = mpz_cmp (a->val, b->val) != 0 ? btor_bv_one (mm, 1)
1843 : btor_bv_zero (mm, 1);
1844 #else
1845 assert (a->len == b->len);
1846 uint32_t i, bit;
1847
1848 res = btor_bv_new (mm, 1);
1849 bit = 1;
1850 for (i = 0; i < a->len; i++)
1851 {
1852 if (a->bits[i] != b->bits[i])
1853 {
1854 bit = 0;
1855 break;
1856 }
1857 }
1858 btor_bv_set_bit (res, 0, !bit);
1859
1860 assert (rem_bits_zero_dbg (res));
1861 #endif
1862 return res;
1863 }
1864
1865 BtorBitVector *
btor_bv_ult(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1866 btor_bv_ult (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1867 {
1868 assert (mm);
1869 assert (a);
1870 assert (b);
1871 assert (a->width == b->width);
1872
1873 BtorBitVector *res;
1874 #ifdef BTOR_USE_GMP
1875 res =
1876 mpz_cmp (a->val, b->val) < 0 ? btor_bv_one (mm, 1) : btor_bv_zero (mm, 1);
1877 #else
1878 assert (a->len == b->len);
1879 uint32_t i, bit;
1880
1881 res = btor_bv_new (mm, 1);
1882 bit = 1;
1883
1884 /* find index on which a and b differ */
1885 for (i = 0; i < a->len && a->bits[i] == b->bits[i]; i++)
1886 ;
1887
1888 /* a >= b */
1889 if (i == a->len || a->bits[i] >= b->bits[i]) bit = 0;
1890
1891 btor_bv_set_bit (res, 0, bit);
1892
1893 assert (rem_bits_zero_dbg (res));
1894 #endif
1895 return res;
1896 }
1897
1898 BtorBitVector *
btor_bv_ulte(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1899 btor_bv_ulte (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1900 {
1901 assert (mm);
1902 assert (a);
1903 assert (b);
1904 assert (a->width == b->width);
1905
1906 BtorBitVector *res;
1907 #ifdef BTOR_USE_GMP
1908 res = mpz_cmp (a->val, b->val) <= 0 ? btor_bv_one (mm, 1)
1909 : btor_bv_zero (mm, 1);
1910 #else
1911 assert (a->len == b->len);
1912 uint32_t i, bit;
1913
1914 res = btor_bv_new (mm, 1);
1915 bit = 1;
1916
1917 /* find index on which a and b differ */
1918 for (i = 0; i < a->len && a->bits[i] == b->bits[i]; i++)
1919 ;
1920
1921 /* a > b */
1922 if (i < a->len && a->bits[i] > b->bits[i]) bit = 0;
1923
1924 btor_bv_set_bit (res, 0, bit);
1925
1926 assert (rem_bits_zero_dbg (res));
1927 #endif
1928 return res;
1929 }
1930
1931 BtorBitVector *
btor_bv_ugt(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1932 btor_bv_ugt (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1933 {
1934 assert (mm);
1935 assert (a);
1936 assert (b);
1937 assert (a->width == b->width);
1938
1939 BtorBitVector *res;
1940 #ifdef BTOR_USE_GMP
1941 res =
1942 mpz_cmp (a->val, b->val) > 0 ? btor_bv_one (mm, 1) : btor_bv_zero (mm, 1);
1943 #else
1944 assert (a->len == b->len);
1945 uint32_t i, bit;
1946
1947 res = btor_bv_new (mm, 1);
1948 bit = 1;
1949
1950 /* find index on which a and b differ */
1951 for (i = 0; i < a->len && a->bits[i] == b->bits[i]; i++)
1952 ;
1953
1954 /* a <= b */
1955 if (i == a->len || a->bits[i] <= b->bits[i]) bit = 0;
1956
1957 btor_bv_set_bit (res, 0, bit);
1958
1959 assert (rem_bits_zero_dbg (res));
1960 #endif
1961 return res;
1962 }
1963
1964 BtorBitVector *
btor_bv_ugte(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1965 btor_bv_ugte (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1966 {
1967 assert (mm);
1968 assert (a);
1969 assert (b);
1970 assert (a->width == b->width);
1971
1972 BtorBitVector *res;
1973 #ifdef BTOR_USE_GMP
1974 res = mpz_cmp (a->val, b->val) >= 0 ? btor_bv_one (mm, 1)
1975 : btor_bv_zero (mm, 1);
1976 #else
1977 assert (a->len == b->len);
1978 uint32_t i, bit;
1979
1980 res = btor_bv_new (mm, 1);
1981 bit = 1;
1982
1983 /* find index on which a and b differ */
1984 for (i = 0; i < a->len && a->bits[i] == b->bits[i]; i++)
1985 ;
1986
1987 /* a < b */
1988 if (i < a->len && a->bits[i] < b->bits[i]) bit = 0;
1989
1990 btor_bv_set_bit (res, 0, bit);
1991
1992 assert (rem_bits_zero_dbg (res));
1993 #endif
1994 return res;
1995 }
1996
1997 BtorBitVector *
btor_bv_slt(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)1998 btor_bv_slt (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
1999 {
2000 assert (mm);
2001 assert (a);
2002 assert (b);
2003 assert (a->width == b->width);
2004
2005 BtorBitVector *res;
2006 uint32_t bw, msb_a, msb_b;
2007
2008 bw = a->width;
2009 msb_a = btor_bv_get_bit (a, bw - 1);
2010 msb_b = btor_bv_get_bit (b, bw - 1);
2011 if (msb_a && !msb_b)
2012 {
2013 res = btor_bv_one (mm, 1);
2014 }
2015 else if (!msb_a && msb_b)
2016 {
2017 res = btor_bv_zero (mm, 1);
2018 }
2019 else
2020 {
2021 res = btor_bv_ult (mm, a, b);
2022 }
2023 return res;
2024 }
2025
2026 BtorBitVector *
btor_bv_slte(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2027 btor_bv_slte (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2028 {
2029 assert (mm);
2030 assert (a);
2031 assert (b);
2032 assert (a->width == b->width);
2033
2034 BtorBitVector *res;
2035 uint32_t bw, msb_a, msb_b;
2036
2037 bw = a->width;
2038 msb_a = btor_bv_get_bit (a, bw - 1);
2039 msb_b = btor_bv_get_bit (b, bw - 1);
2040 if (msb_a && !msb_b)
2041 {
2042 res = btor_bv_one (mm, 1);
2043 }
2044 else if (!msb_a && msb_b)
2045 {
2046 res = btor_bv_zero (mm, 1);
2047 }
2048 else
2049 {
2050 res = btor_bv_ulte (mm, a, b);
2051 }
2052 return res;
2053 }
2054
2055 BtorBitVector *
btor_bv_sgt(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2056 btor_bv_sgt (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2057 {
2058 assert (mm);
2059 assert (a);
2060 assert (b);
2061 assert (a->width == b->width);
2062
2063 BtorBitVector *res;
2064 uint32_t bw, msb_a, msb_b;
2065
2066 bw = a->width;
2067 msb_a = btor_bv_get_bit (a, bw - 1);
2068 msb_b = btor_bv_get_bit (b, bw - 1);
2069 if (msb_a && !msb_b)
2070 {
2071 res = btor_bv_zero (mm, 1);
2072 }
2073 else if (!msb_a && msb_b)
2074 {
2075 res = btor_bv_one (mm, 1);
2076 }
2077 else
2078 {
2079 res = btor_bv_ugt (mm, a, b);
2080 }
2081 return res;
2082 }
2083
2084 BtorBitVector *
btor_bv_sgte(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2085 btor_bv_sgte (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2086 {
2087 assert (mm);
2088 assert (a);
2089 assert (b);
2090 assert (a->width == b->width);
2091
2092 BtorBitVector *res;
2093 uint32_t bw, msb_a, msb_b;
2094
2095 bw = a->width;
2096 msb_a = btor_bv_get_bit (a, bw - 1);
2097 msb_b = btor_bv_get_bit (b, bw - 1);
2098 if (msb_a && !msb_b)
2099 {
2100 res = btor_bv_zero (mm, 1);
2101 }
2102 else if (!msb_a && msb_b)
2103 {
2104 res = btor_bv_one (mm, 1);
2105 }
2106 else
2107 {
2108 res = btor_bv_ugte (mm, a, b);
2109 }
2110 return res;
2111 }
2112
2113 BtorBitVector *
btor_bv_sll_uint64(BtorMemMgr * mm,const BtorBitVector * a,uint64_t shift)2114 btor_bv_sll_uint64 (BtorMemMgr *mm, const BtorBitVector *a, uint64_t shift)
2115 {
2116 assert (mm);
2117 assert (a);
2118
2119 BtorBitVector *res;
2120 uint32_t bw = a->width;
2121
2122 res = btor_bv_new (mm, bw);
2123 if (shift >= bw) return res;
2124
2125 #ifdef BTOR_USE_GMP
2126 mpz_mul_2exp (res->val, a->val, shift);
2127 mpz_fdiv_r_2exp (res->val, res->val, bw);
2128 #else
2129 uint32_t skip, i, j, k;
2130 BTOR_BV_TYPE v;
2131
2132 k = shift % BTOR_BV_TYPE_BW;
2133 skip = shift / BTOR_BV_TYPE_BW;
2134
2135 v = 0;
2136 for (i = a->len - 1, j = res->len - 1 - skip;; i--, j--)
2137 {
2138 v = (k == 0) ? a->bits[i] : v | (a->bits[i] << k);
2139 res->bits[j] = v;
2140 v = (k == 0) ? a->bits[i] : a->bits[i] >> (BTOR_BV_TYPE_BW - k);
2141 if (i == 0 || j == 0) break;
2142 }
2143 set_rem_bits_to_zero (res);
2144 assert (rem_bits_zero_dbg (res));
2145 #endif
2146 assert (check_bits_sll_dbg (a, res, shift));
2147 return res;
2148 }
2149
2150 static bool
shift_is_uint64(BtorMemMgr * mm,const BtorBitVector * b,uint64_t * res)2151 shift_is_uint64 (BtorMemMgr *mm,
2152 const BtorBitVector *b,
2153 uint64_t *res)
2154 {
2155 assert (mm);
2156 assert (b);
2157 assert (res);
2158
2159 uint64_t zeroes;
2160 BtorBitVector *shift;
2161
2162 if (b->width <= 64)
2163 {
2164 *res = btor_bv_to_uint64 (b);
2165 return true;
2166 }
2167
2168 zeroes = btor_bv_get_num_leading_zeros (b);
2169 if (zeroes < b->width - 64) return false;
2170
2171 shift =
2172 btor_bv_slice (mm, b, zeroes < b->width ? b->width - 1 - zeroes : 0, 0);
2173 assert (shift->width <= 64);
2174 *res = btor_bv_to_uint64 (shift);
2175 btor_bv_free (mm, shift);
2176 return true;
2177 }
2178
2179 BtorBitVector *
btor_bv_sll(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2180 btor_bv_sll (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2181 {
2182 assert (mm);
2183 assert (a);
2184 assert (b);
2185 assert (a->width == b->width);
2186
2187 uint64_t ushift;
2188
2189 if (shift_is_uint64 (mm, b, &ushift))
2190 {
2191 return btor_bv_sll_uint64 (mm, a, ushift);
2192 }
2193 return btor_bv_new (mm, a->width);
2194 }
2195
2196 BtorBitVector *
btor_bv_sra(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2197 btor_bv_sra (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2198 {
2199 assert (mm);
2200 assert (a);
2201 assert (b);
2202 assert (a->width == b->width);
2203
2204 BtorBitVector *res;
2205 if (btor_bv_get_bit (a, a->width - 1))
2206 {
2207 BtorBitVector *not_a = btor_bv_not (mm, a);
2208 BtorBitVector *not_a_srl_b = btor_bv_srl (mm, not_a, b);
2209 res = btor_bv_not (mm, not_a_srl_b);
2210 btor_bv_free (mm, not_a);
2211 btor_bv_free (mm, not_a_srl_b);
2212 }
2213 else
2214 {
2215 res = btor_bv_srl (mm, a, b);
2216 }
2217 #ifndef BTOR_USE_GMP
2218 assert (rem_bits_zero_dbg (res));
2219 #endif
2220 return res;
2221 }
2222
2223 BtorBitVector *
btor_bv_srl_uint64(BtorMemMgr * mm,const BtorBitVector * a,uint64_t shift)2224 btor_bv_srl_uint64 (BtorMemMgr *mm, const BtorBitVector *a, uint64_t shift)
2225 {
2226 assert (mm);
2227 assert (a);
2228
2229 BtorBitVector *res;
2230
2231 res = btor_bv_new (mm, a->width);
2232 if (shift >= a->width) return res;
2233 #ifdef BTOR_USE_GMP
2234 mpz_fdiv_q_2exp (res->val, a->val, shift);
2235 #else
2236 uint32_t skip, i, j, k;
2237 BTOR_BV_TYPE v;
2238 k = shift % BTOR_BV_TYPE_BW;
2239 skip = shift / BTOR_BV_TYPE_BW;
2240 v = 0;
2241 for (i = 0, j = skip; i < a->len && j < a->len; i++, j++)
2242 {
2243 v = (k == 0) ? a->bits[i] : v | (a->bits[i] >> k);
2244 res->bits[j] = v;
2245 v = (k == 0) ? a->bits[i] : a->bits[i] << (BTOR_BV_TYPE_BW - k);
2246 }
2247 assert (rem_bits_zero_dbg (res));
2248 #endif
2249 return res;
2250 }
2251
2252 BtorBitVector *
btor_bv_srl(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2253 btor_bv_srl (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2254 {
2255 assert (mm);
2256 assert (a);
2257 assert (b);
2258 assert (a->width == b->width);
2259
2260 uint64_t ushift;
2261
2262 if (shift_is_uint64 (mm, b, &ushift))
2263 {
2264 return btor_bv_srl_uint64 (mm, a, ushift);
2265 }
2266 return btor_bv_new (mm, a->width);
2267 }
2268
2269 BtorBitVector *
btor_bv_mul(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2270 btor_bv_mul (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2271 {
2272 assert (mm);
2273 assert (a);
2274 assert (b);
2275 assert (a->width == b->width);
2276
2277 BtorBitVector *res;
2278 uint32_t bw = a->width;
2279 #ifdef BTOR_USE_GMP
2280 res = btor_bv_new (mm, bw);
2281 mpz_mul (res->val, a->val, b->val);
2282 mpz_fdiv_r_2exp (res->val, res->val, bw);
2283 #else
2284 assert (a->len == b->len);
2285 uint32_t i;
2286 uint64_t x, y;
2287 BtorBitVector *and, *shift, *add;
2288
2289 if (bw <= 64)
2290 {
2291 x = btor_bv_to_uint64 (a);
2292 y = btor_bv_to_uint64 (b);
2293 res = btor_bv_uint64_to_bv (mm, x * y, bw);
2294 }
2295 else
2296 {
2297 res = btor_bv_new (mm, bw);
2298 for (i = 0; i < bw; i++)
2299 {
2300 if (btor_bv_get_bit (b, i))
2301 and = btor_bv_copy (mm, a);
2302 else
2303 and = btor_bv_new (mm, bw);
2304 shift = btor_bv_sll_uint64 (mm, and, i);
2305 add = btor_bv_add (mm, res, shift);
2306 btor_bv_free (mm, and);
2307 btor_bv_free (mm, shift);
2308 btor_bv_free (mm, res);
2309 res = add;
2310 }
2311 }
2312 #endif
2313 return res;
2314 }
2315
2316 #ifndef BTOR_USE_GMP
2317 static void
udiv_urem_bv(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b,BtorBitVector ** q,BtorBitVector ** r)2318 udiv_urem_bv (BtorMemMgr *mm,
2319 const BtorBitVector *a,
2320 const BtorBitVector *b,
2321 BtorBitVector **q,
2322 BtorBitVector **r)
2323 {
2324 assert (mm);
2325 assert (a);
2326 assert (b);
2327 assert (a->width == b->width);
2328
2329 assert (a->len == b->len);
2330 int64_t i;
2331 bool is_true;
2332 uint64_t x, y, z;
2333 uint32_t bw = a->width;
2334
2335 BtorBitVector *neg_b, *quot, *rem, *ult, *eq, *tmp;
2336
2337 if (bw <= 64)
2338 {
2339 x = btor_bv_to_uint64 (a);
2340 y = btor_bv_to_uint64 (b);
2341 if (y == 0)
2342 {
2343 y = x;
2344 x = UINT64_MAX;
2345 }
2346 else
2347 {
2348 z = x / y;
2349 y = x % y;
2350 x = z;
2351 }
2352 quot = btor_bv_uint64_to_bv (mm, x, bw);
2353 rem = btor_bv_uint64_to_bv (mm, y, bw);
2354 }
2355 else
2356 {
2357 neg_b = btor_bv_neg (mm, b);
2358 quot = btor_bv_new (mm, bw);
2359 rem = btor_bv_new (mm, bw);
2360
2361 for (i = bw - 1; i >= 0; i--)
2362 {
2363 tmp = btor_bv_sll_uint64 (mm, rem, 1);
2364 btor_bv_free (mm, rem);
2365 rem = tmp;
2366 btor_bv_set_bit (rem, 0, btor_bv_get_bit (a, i));
2367
2368 ult = btor_bv_ult (mm, b, rem);
2369 is_true = btor_bv_is_true (ult);
2370 btor_bv_free (mm, ult);
2371
2372 if (is_true) goto UDIV_UREM_SUBTRACT;
2373
2374 eq = btor_bv_eq (mm, b, rem);
2375 is_true = btor_bv_is_true (eq);
2376 btor_bv_free (mm, eq);
2377
2378 if (is_true)
2379 {
2380 UDIV_UREM_SUBTRACT:
2381 tmp = btor_bv_add (mm, rem, neg_b);
2382 btor_bv_free (mm, rem);
2383 rem = tmp;
2384 btor_bv_set_bit (quot, i, 1);
2385 }
2386 }
2387 btor_bv_free (mm, neg_b);
2388 }
2389
2390 if (q)
2391 *q = quot;
2392 else
2393 btor_bv_free (mm, quot);
2394
2395 if (r)
2396 *r = rem;
2397 else
2398 btor_bv_free (mm, rem);
2399 }
2400 #endif
2401
2402 BtorBitVector *
btor_bv_udiv(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2403 btor_bv_udiv (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2404 {
2405 assert (mm);
2406 assert (a);
2407 assert (b);
2408 assert (a->width == b->width);
2409
2410 BtorBitVector *res;
2411 #ifdef BTOR_USE_GMP
2412 uint32_t bw = a->width;
2413 if (btor_bv_is_zero (b)) return btor_bv_ones (mm, bw);
2414 res = btor_bv_new (mm, bw);
2415 mpz_fdiv_q (res->val, a->val, b->val);
2416 mpz_fdiv_r_2exp (res->val, res->val, bw);
2417 #else
2418 assert (a->len == b->len);
2419 udiv_urem_bv (mm, a, b, &res, 0);
2420 assert (res);
2421 #endif
2422 return res;
2423 }
2424
2425 BtorBitVector *
btor_bv_urem(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2426 btor_bv_urem (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2427 {
2428 assert (mm);
2429 assert (a);
2430 assert (b);
2431 assert (a->width == b->width);
2432
2433 BtorBitVector *res;
2434 #ifdef BTOR_USE_GMP
2435 uint32_t bw = a->width;
2436 if (btor_bv_is_zero (b)) return btor_bv_copy (mm, a);
2437 res = btor_bv_new (mm, bw);
2438 mpz_fdiv_r (res->val, a->val, b->val);
2439 mpz_fdiv_r_2exp (res->val, res->val, bw);
2440 #else
2441 assert (a->len == b->len);
2442 udiv_urem_bv (mm, a, b, 0, &res);
2443 assert (res);
2444 #endif
2445 return res;
2446 }
2447
2448 BtorBitVector *
btor_bv_sdiv(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2449 btor_bv_sdiv (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2450 {
2451 assert (mm);
2452 assert (a);
2453 assert (b);
2454 assert (a->width == b->width);
2455
2456 bool is_signed_a, is_signed_b;
2457 uint32_t bw;
2458 BtorBitVector *res, *div, *neg_a, *neg_b;
2459
2460 bw = a->width;
2461 is_signed_a = btor_bv_get_bit (a, bw - 1);
2462 is_signed_b = btor_bv_get_bit (b, bw - 1);
2463
2464 if (is_signed_a && !is_signed_b)
2465 {
2466 neg_a = btor_bv_neg (mm, a);
2467 div = btor_bv_udiv (mm, neg_a, b);
2468 res = btor_bv_neg (mm, div);
2469 btor_bv_free (mm, neg_a);
2470 btor_bv_free (mm, div);
2471 }
2472 else if (!is_signed_a && is_signed_b)
2473 {
2474 neg_b = btor_bv_neg (mm, b);
2475 div = btor_bv_udiv (mm, a, neg_b);
2476 res = btor_bv_neg (mm, div);
2477 btor_bv_free (mm, neg_b);
2478 btor_bv_free (mm, div);
2479 }
2480 else if (is_signed_a && is_signed_b)
2481 {
2482 neg_a = btor_bv_neg (mm, a);
2483 neg_b = btor_bv_neg (mm, b);
2484 res = btor_bv_udiv (mm, neg_a, neg_b);
2485 btor_bv_free (mm, neg_a);
2486 btor_bv_free (mm, neg_b);
2487 }
2488 else
2489 {
2490 res = btor_bv_udiv (mm, a, b);
2491 }
2492 return res;
2493 }
2494
2495 BtorBitVector *
btor_bv_srem(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2496 btor_bv_srem (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2497 {
2498 assert (mm);
2499 assert (a);
2500 assert (b);
2501 assert (a->width == b->width);
2502
2503 bool is_signed_a, is_signed_b;
2504 uint32_t bw;
2505 BtorBitVector *res, *rem, *neg_a, *neg_b;
2506
2507 bw = a->width;
2508 is_signed_a = btor_bv_get_bit (a, bw - 1);
2509 is_signed_b = btor_bv_get_bit (b, bw - 1);
2510
2511 if (is_signed_a && !is_signed_b)
2512 {
2513 neg_a = btor_bv_neg (mm, a);
2514 rem = btor_bv_urem (mm, neg_a, b);
2515 res = btor_bv_neg (mm, rem);
2516 btor_bv_free (mm, neg_a);
2517 btor_bv_free (mm, rem);
2518 }
2519 else if (!is_signed_a && is_signed_b)
2520 {
2521 neg_b = btor_bv_neg (mm, b);
2522 res = btor_bv_urem (mm, a, neg_b);
2523 btor_bv_free (mm, neg_b);
2524 }
2525 else if (is_signed_a && is_signed_b)
2526 {
2527 neg_a = btor_bv_neg (mm, a);
2528 neg_b = btor_bv_neg (mm, b);
2529 rem = btor_bv_urem (mm, neg_a, neg_b);
2530 res = btor_bv_neg (mm, rem);
2531 btor_bv_free (mm, neg_a);
2532 btor_bv_free (mm, neg_b);
2533 btor_bv_free (mm, rem);
2534 }
2535 else
2536 {
2537 res = btor_bv_urem (mm, a, b);
2538 }
2539 return res;
2540 }
2541
2542 BtorBitVector *
btor_bv_concat(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2543 btor_bv_concat (BtorMemMgr *mm, const BtorBitVector *a, const BtorBitVector *b)
2544 {
2545 assert (mm);
2546 assert (a);
2547 assert (b);
2548
2549 BtorBitVector *res;
2550 uint32_t bw = a->width + b->width;
2551 #ifdef BTOR_USE_GMP
2552 res = btor_bv_new (mm, bw);
2553 mpz_mul_2exp (res->val, a->val, b->width);
2554 mpz_add (res->val, res->val, b->val);
2555 mpz_fdiv_r_2exp (res->val, res->val, bw);
2556 #else
2557 int64_t i, j, k;
2558 BTOR_BV_TYPE v;
2559
2560 res = btor_bv_new (mm, bw);
2561
2562 j = res->len - 1;
2563
2564 /* copy bits from bit vector b */
2565 for (i = b->len - 1; i >= 0; i--) res->bits[j--] = b->bits[i];
2566
2567 k = b->width % BTOR_BV_TYPE_BW;
2568
2569 /* copy bits from bit vector a */
2570 if (k == 0)
2571 {
2572 assert (j >= 0);
2573 for (i = a->len - 1; i >= 0; i--) res->bits[j--] = a->bits[i];
2574 }
2575 else
2576 {
2577 j += 1;
2578 assert (res->bits[j] >> k == 0);
2579 v = res->bits[j];
2580 for (i = a->len - 1; i >= 0; i--)
2581 {
2582 v = v | (a->bits[i] << k);
2583 assert (j >= 0);
2584 res->bits[j--] = v;
2585 v = a->bits[i] >> (BTOR_BV_TYPE_BW - k);
2586 }
2587 assert (j <= 0);
2588 if (j == 0) res->bits[j] = v;
2589 }
2590
2591 assert (rem_bits_zero_dbg (res));
2592 #endif
2593 return res;
2594 }
2595
2596 BtorBitVector *
btor_bv_slice(BtorMemMgr * mm,const BtorBitVector * bv,uint32_t upper,uint32_t lower)2597 btor_bv_slice (BtorMemMgr *mm,
2598 const BtorBitVector *bv,
2599 uint32_t upper,
2600 uint32_t lower)
2601 {
2602 assert (mm);
2603 assert (bv);
2604
2605 BtorBitVector *res;
2606 uint32_t bw = upper - lower + 1;
2607 #ifdef BTOR_USE_GMP
2608 res = btor_bv_new (mm, bw);
2609 mpz_fdiv_r_2exp (res->val, bv->val, upper + 1);
2610 mpz_fdiv_q_2exp (res->val, res->val, lower);
2611 #else
2612 uint32_t i, j;
2613
2614 res = btor_bv_new (mm, bw);
2615 for (i = lower, j = 0; i <= upper; i++)
2616 btor_bv_set_bit (res, j++, btor_bv_get_bit (bv, i));
2617
2618 assert (rem_bits_zero_dbg (res));
2619 #endif
2620 return res;
2621 }
2622
2623 BtorBitVector *
btor_bv_sext(BtorMemMgr * mm,const BtorBitVector * bv,uint32_t len)2624 btor_bv_sext (BtorMemMgr *mm, const BtorBitVector *bv, uint32_t len)
2625 {
2626 assert (mm);
2627 assert (bv);
2628
2629 BtorBitVector *res;
2630 uint32_t bw;
2631
2632 if (len == 0)
2633 {
2634 return btor_bv_copy (mm, bv);
2635 }
2636
2637 bw = bv->width;
2638 #ifdef BTOR_USE_GMP
2639 if (btor_bv_get_bit (bv, bw - 1))
2640 {
2641 size_t i, n;
2642 res = btor_bv_copy (mm, bv);
2643 res->width += len;
2644 for (i = bw, n = bw + len; i < n; i++) mpz_setbit (res->val, i);
2645 }
2646 else
2647 {
2648 res = btor_bv_uext (mm, bv, len);
2649 }
2650 #else
2651 BtorBitVector *tmp;
2652 tmp = btor_bv_get_bit (bv, bw - 1) ? btor_bv_ones (mm, len)
2653 : btor_bv_zero (mm, len);
2654 res = btor_bv_concat (mm, tmp, bv);
2655 btor_bv_free (mm, tmp);
2656 assert (rem_bits_zero_dbg (res));
2657 #endif
2658 return res;
2659 }
2660
2661 BtorBitVector *
btor_bv_uext(BtorMemMgr * mm,const BtorBitVector * bv,uint32_t len)2662 btor_bv_uext (BtorMemMgr *mm, const BtorBitVector *bv, uint32_t len)
2663 {
2664 assert (mm);
2665 assert (bv);
2666
2667 BtorBitVector *res;
2668 uint32_t bw;
2669
2670 if (len == 0)
2671 {
2672 return btor_bv_copy (mm, bv);
2673 }
2674
2675 bw = bv->width + len;
2676 res = btor_bv_new (mm, bw);
2677 #ifdef BTOR_USE_GMP
2678 mpz_set (res->val, bv->val);
2679 #else
2680 memcpy (
2681 res->bits + res->len - bv->len, bv->bits, sizeof (*(bv->bits)) * bv->len);
2682 #endif
2683 return res;
2684 }
2685
2686 BtorBitVector *
btor_bv_ite(BtorMemMgr * mm,const BtorBitVector * c,const BtorBitVector * t,const BtorBitVector * e)2687 btor_bv_ite (BtorMemMgr *mm,
2688 const BtorBitVector *c,
2689 const BtorBitVector *t,
2690 const BtorBitVector *e)
2691 {
2692 assert (c);
2693 assert (t);
2694 assert (e);
2695 assert (t->width == e->width);
2696
2697 BtorBitVector *res;
2698 #ifdef BTOR_USE_GMP
2699 res = btor_bv_is_one (c) ? btor_bv_copy (mm, t) : btor_bv_copy (mm, e);
2700 #else
2701 assert (c->len == 1);
2702 assert (t->len > 0);
2703 assert (t->len == e->len);
2704 BTOR_BV_TYPE cc, nn;
2705 uint32_t i;
2706
2707 cc = btor_bv_get_bit (c, 0) ? (~(BTOR_BV_TYPE) 0) : 0;
2708 nn = ~cc;
2709
2710 res = btor_bv_new (mm, t->width);
2711 for (i = 0; i < t->len; i++)
2712 res->bits[i] = (cc & t->bits[i]) | (nn & e->bits[i]);
2713
2714 assert (rem_bits_zero_dbg (res));
2715 #endif
2716 return res;
2717 }
2718
2719 BtorBitVector *
btor_bv_flipped_bit(BtorMemMgr * mm,const BtorBitVector * bv,uint32_t pos)2720 btor_bv_flipped_bit (BtorMemMgr *mm, const BtorBitVector *bv, uint32_t pos)
2721 {
2722 assert (bv);
2723 assert (pos < bv->width);
2724
2725 BtorBitVector *res;
2726 res = btor_bv_copy (mm, bv);
2727 btor_bv_flip_bit (res, pos);
2728 return res;
2729 }
2730
2731 BtorBitVector *
btor_bv_flipped_bit_range(BtorMemMgr * mm,const BtorBitVector * bv,uint32_t upper,uint32_t lower)2732 btor_bv_flipped_bit_range (BtorMemMgr *mm,
2733 const BtorBitVector *bv,
2734 uint32_t upper,
2735 uint32_t lower)
2736 {
2737 assert (mm);
2738 assert (lower <= upper);
2739 assert (upper < bv->width);
2740
2741 BtorBitVector *res;
2742 uint32_t i;
2743
2744 res = btor_bv_copy (mm, bv);
2745 for (i = lower; i <= upper; i++)
2746 btor_bv_set_bit (res, i, btor_bv_get_bit (res, i) ? 0 : 1);
2747 return res;
2748 }
2749
2750 /*------------------------------------------------------------------------*/
2751
2752 bool
btor_bv_is_umulo(BtorMemMgr * mm,const BtorBitVector * a,const BtorBitVector * b)2753 btor_bv_is_umulo (BtorMemMgr *mm,
2754 const BtorBitVector *a,
2755 const BtorBitVector *b)
2756 {
2757 assert (mm);
2758 assert (a);
2759 assert (b);
2760 assert (a->width == b->width);
2761 #ifndef BTOR_USE_GMP
2762 assert (a->len == b->len);
2763 #endif
2764
2765 bool res = false;
2766 uint32_t bw = a->width;
2767
2768 if (a->width > 1)
2769 {
2770 #ifdef BTOR_USE_GMP
2771 (void) mm;
2772 mpz_t mul;
2773 mpz_init (mul);
2774 mpz_mul (mul, a->val, b->val);
2775 mpz_fdiv_q_2exp (mul, mul, bw);
2776 res = mpz_cmp_ui (mul, 0) != 0;
2777 mpz_clear (mul);
2778 #else
2779 BtorBitVector *aext, *bext, *mul, *o;
2780 aext = btor_bv_uext (mm, a, bw);
2781 bext = btor_bv_uext (mm, b, bw);
2782 mul = btor_bv_mul (mm, aext, bext);
2783 o = btor_bv_slice (mm, mul, mul->width - 1, bw);
2784 if (!btor_bv_is_zero (o)) res = true;
2785 btor_bv_free (mm, aext);
2786 btor_bv_free (mm, bext);
2787 btor_bv_free (mm, mul);
2788 btor_bv_free (mm, o);
2789 #endif
2790 }
2791 return res;
2792 }
2793
2794 /*------------------------------------------------------------------------*/
2795
2796 #if 0
2797 BtorBitVector *
2798 btor_bv_gcd_ext (Btor * btor,
2799 const BtorBitVector * bv1,
2800 const BtorBitVector * bv2,
2801 BtorBitVector ** fx,
2802 BtorBitVector ** fy)
2803 {
2804 assert (bv1);
2805 assert (bv2);
2806 assert (bv1->width == bv2->width);
2807 assert (btor_bv_compare (bv1, bv2) <= 0);
2808 assert (fx);
2809 assert (fy);
2810
2811 BtorBitVector *a, *b, *x, *y, *lx, *ly, *gcd = 0;
2812 BtorBitVector *zero, *mul, *neg, *tx, *ty, *r, *q = 0;
2813
2814 zero = btor_bv_new (btor->mm, bv1->width);
2815
2816 a = btor_bv_copy (btor->mm, bv1);
2817 b = btor_bv_copy (btor->mm, bv2);
2818
2819 x = btor_bv_copy (btor->mm, zero); // 0
2820 y = btor_bv_flipped_bit (btor->mm, zero, 0); // 1
2821
2822 lx = btor_bv_flipped_bit (btor->mm, zero, 0); // 1
2823 ly = btor_bv_copy (btor->mm, zero); // 0
2824
2825 r = btor_bv_copy (btor->mm, bv1);
2826
2827 while (btor_bv_compare (b, zero) > 0)
2828 {
2829 if (gcd) btor_bv_free (btor->mm, gcd);
2830 gcd = btor_bv_copy (btor->mm, r);
2831
2832 btor_bv_free (btor->mm, r);
2833 r = btor_bv_urem (btor->mm, a, b); // r = a % b
2834
2835 if (q) btor_bv_free (btor->mm, q);
2836 q = btor_bv_udiv (btor->mm, a, b); // q = a / b
2837
2838 btor_bv_free (btor->mm, a);
2839 a = btor_bv_copy (btor->mm, b); // a = b
2840 btor_bv_free (btor->mm, b);
2841 b = btor_bv_copy (btor->mm, r); // b = r
2842
2843 tx = btor_bv_copy (btor->mm, x); // tx = x
2844 mul = btor_bv_mul (btor->mm, x, q);
2845 neg = btor_bv_neg (btor->mm, mul);
2846 btor_bv_free (btor->mm, x);
2847 x = btor_bv_add (btor->mm, lx, neg); // x = lx - x * q
2848 btor_bv_free (btor->mm, neg);
2849 btor_bv_free (btor->mm, mul);
2850 btor_bv_free (btor->mm, lx);
2851 lx = tx; // lx = tx
2852
2853 ty = btor_bv_copy (btor->mm, y); // ty = y
2854 mul = btor_bv_mul (btor->mm, y, q);
2855 neg = btor_bv_neg (btor->mm, mul);
2856 btor_bv_free (btor->mm, y);
2857 y = btor_bv_add (btor->mm, ly, neg); // y = ly - y * q
2858 btor_bv_free (btor->mm, neg);
2859 btor_bv_free (btor->mm, mul);
2860 btor_bv_free (btor->mm, ly);
2861 ly = ty; // ly = ty
2862 }
2863
2864 *fx = lx;
2865 *fy = ly;
2866 btor_bv_free (btor->mm, r);
2867 btor_bv_free (btor->mm, q);
2868 btor_bv_free (btor->mm, a);
2869 btor_bv_free (btor->mm, b);
2870 btor_bv_free (btor->mm, x);
2871 btor_bv_free (btor->mm, y);
2872 btor_bv_free (btor->mm, zero);
2873 return gcd;
2874 }
2875 #endif
2876
2877 /* Calculate modular inverse for bv by means of the Extended Euclidian
2878 * Algorithm. Note that c must be odd (the greatest
2879 * common divisor gcd (c, 2^bw) must be and is in this case always 1). */
2880 BtorBitVector *
btor_bv_mod_inverse(BtorMemMgr * mm,const BtorBitVector * bv)2881 btor_bv_mod_inverse (BtorMemMgr *mm, const BtorBitVector *bv)
2882 {
2883 assert (mm);
2884 assert (bv);
2885 assert (btor_bv_get_bit (bv, 0)); /* bv must be odd */
2886
2887 /* a = 2^bw
2888 * b = bv
2889 * lx * a + ly * b = gcd (a, b) = 1
2890 * -> lx * a = lx * 2^bw = 0 (2^bw_[bw] = 0)
2891 * -> ly * b = bv^-1 * bv = 1
2892 * -> ly is modular inverse of bv */
2893
2894 BtorBitVector *res;
2895 uint32_t bw;
2896
2897 bw = bv->width;
2898
2899 #ifdef BTOR_USE_GMP
2900 BTOR_NEW (mm, res);
2901 res->width = bw;
2902 #if 1
2903 if (bw == 1)
2904 {
2905 mpz_init_set_ui (res->val, 1);
2906 }
2907 else
2908 {
2909 mpz_t twobw;
2910 mpz_init (twobw);
2911 mpz_init (res->val);
2912 mpz_setbit (twobw, bw);
2913 mpz_invert (res->val, bv->val, twobw);
2914 mpz_fdiv_r_2exp (res->val, res->val, bw);
2915 mpz_clear (twobw);
2916 }
2917 #else
2918 uint32_t ebw = bw + 1;
2919 mpz_t a, b, y, ty, q, yq, r;
2920
2921 BTOR_NEW (mm, res);
2922 res->width = bw;
2923 mpz_init (res->val);
2924
2925 mpz_init (a);
2926 mpz_setbit (a, bw); /* 2^bw */
2927
2928 mpz_init_set (b, bv->val);
2929
2930 mpz_init_set_ui (y, 1);
2931 mpz_init (ty);
2932 mpz_init (yq);
2933
2934 mpz_init (q);
2935 mpz_init (r);
2936
2937 while (mpz_cmp_ui (b, 0))
2938 {
2939 mpz_tdiv_qr (q, r, a, b);
2940 mpz_fdiv_r_2exp (q, q, ebw);
2941 mpz_fdiv_r_2exp (r, r, ebw);
2942
2943 mpz_set (a, b);
2944 mpz_set (b, r);
2945 mpz_set (ty, y);
2946 mpz_mul (yq, y, q);
2947 mpz_fdiv_r_2exp (yq, yq, ebw);
2948 mpz_sub (y, res->val, yq); /* y = ly - y * q */
2949 mpz_fdiv_r_2exp (y, y, ebw);
2950 mpz_set (res->val, ty);
2951 }
2952 mpz_fdiv_r_2exp (res->val, res->val, bw);
2953
2954 mpz_clear (a);
2955 mpz_clear (b);
2956 mpz_clear (y);
2957 mpz_clear (ty);
2958 mpz_clear (yq);
2959 mpz_clear (q);
2960 mpz_clear (r);
2961 #endif
2962
2963 #ifndef NDEBUG
2964 mpz_t ty;
2965 assert (res->width == bv->width);
2966 mpz_init (ty);
2967 mpz_mul (ty, bv->val, res->val);
2968 mpz_fdiv_r_2exp (ty, ty, bw);
2969 assert (!mpz_cmp_ui (ty, 1));
2970 mpz_clear (ty);
2971 #endif
2972 #else
2973 uint32_t i;
2974 BtorBitVector *a, *b, *y, *ly, *ty, *q, *yq, *r;
2975 uint32_t ebw = bw + 1;
2976
2977 a = btor_bv_new (mm, ebw);
2978 btor_bv_set_bit (a, bw, 1); /* 2^bw */
2979
2980 b = btor_bv_new (mm, ebw); /* extend to bw of a */
2981 for (i = 0; i < bw; i++) btor_bv_set_bit (b, i, btor_bv_get_bit (bv, i));
2982
2983 y = btor_bv_one (mm, ebw);
2984 ly = btor_bv_new (mm, ebw);
2985
2986 while (!btor_bv_is_zero (b))
2987 {
2988 udiv_urem_bv (mm, a, b, &q, &r);
2989
2990 btor_bv_free (mm, a);
2991
2992 a = b;
2993 b = r;
2994
2995 ty = y;
2996 yq = btor_bv_mul (mm, y, q);
2997 btor_bv_free (mm, q);
2998 y = btor_bv_sub (mm, ly, yq); /* y = ly - y * q */
2999 btor_bv_free (mm, yq);
3000
3001 btor_bv_free (mm, ly);
3002 ly = ty;
3003 }
3004
3005 res = btor_bv_slice (mm, ly, bv->width - 1, 0);
3006
3007 #ifndef NDEBUG
3008 assert (res->width == bv->width);
3009 ty = btor_bv_mul (mm, bv, res);
3010 assert (btor_bv_is_one (ty));
3011 btor_bv_free (mm, ty);
3012 #endif
3013 btor_bv_free (mm, ly);
3014 btor_bv_free (mm, y);
3015 btor_bv_free (mm, b);
3016 btor_bv_free (mm, a);
3017 #endif
3018
3019 return res;
3020 }
3021
3022 /*------------------------------------------------------------------------*/
3023
3024 BtorSpecialConstBitVector
btor_bv_is_special_const(const BtorBitVector * bv)3025 btor_bv_is_special_const (const BtorBitVector *bv)
3026 {
3027 assert (bv);
3028
3029 if (btor_bv_is_zero (bv)) return BTOR_SPECIAL_CONST_BV_ZERO;
3030 if (btor_bv_is_one (bv))
3031 return bv->width == 1 ? BTOR_SPECIAL_CONST_BV_ONE_ONES
3032 : BTOR_SPECIAL_CONST_BV_ONE;
3033 if (btor_bv_is_ones (bv))
3034 {
3035 assert (bv->width > 1);
3036 return BTOR_SPECIAL_CONST_BV_ONES;
3037 }
3038 return BTOR_SPECIAL_CONST_BV_NONE;
3039 }
3040
3041 /*------------------------------------------------------------------------*/
3042
3043 BtorBitVectorTuple *
btor_bv_new_tuple(BtorMemMgr * mm,uint32_t arity)3044 btor_bv_new_tuple (BtorMemMgr *mm, uint32_t arity)
3045 {
3046 assert (mm);
3047
3048 BtorBitVectorTuple *res = 0;
3049
3050 BTOR_CNEW (mm, res);
3051 if (arity) BTOR_CNEWN (mm, res->bv, arity);
3052 res->arity = arity;
3053 return res;
3054 }
3055
3056 void
btor_bv_add_to_tuple(BtorMemMgr * mm,BtorBitVectorTuple * t,const BtorBitVector * bv,uint32_t pos)3057 btor_bv_add_to_tuple (BtorMemMgr *mm,
3058 BtorBitVectorTuple *t,
3059 const BtorBitVector *bv,
3060 uint32_t pos)
3061 {
3062 assert (mm);
3063 assert (t);
3064 assert (bv);
3065 assert (pos < t->arity);
3066 assert (!t->bv[pos]);
3067 t->bv[pos] = btor_bv_copy (mm, bv);
3068 }
3069
3070 void
btor_bv_free_tuple(BtorMemMgr * mm,BtorBitVectorTuple * t)3071 btor_bv_free_tuple (BtorMemMgr *mm, BtorBitVectorTuple *t)
3072 {
3073 assert (mm);
3074 assert (t);
3075
3076 uint32_t i;
3077
3078 if (t->arity)
3079 {
3080 for (i = 0; i < t->arity; i++) btor_bv_free (mm, t->bv[i]);
3081 btor_mem_free (mm, t->bv, sizeof (BtorBitVectorTuple *) * t->arity);
3082 }
3083 btor_mem_free (mm, t, sizeof (BtorBitVectorTuple));
3084 }
3085
3086 int32_t
btor_bv_compare_tuple(const BtorBitVectorTuple * t0,const BtorBitVectorTuple * t1)3087 btor_bv_compare_tuple (const BtorBitVectorTuple *t0,
3088 const BtorBitVectorTuple *t1)
3089 {
3090 assert (t0);
3091 assert (t1);
3092
3093 uint32_t i;
3094 if (t0->arity != t1->arity) return -1;
3095
3096 for (i = 0; i < t0->arity; i++)
3097 {
3098 assert (t0->bv[i]);
3099 assert (t1->bv[i]);
3100 if (t0->bv[i]->width != t1->bv[i]->width
3101 || btor_bv_compare (t0->bv[i], t1->bv[i]) != 0)
3102 return 1;
3103 }
3104 return 0;
3105 }
3106
3107 uint32_t
btor_bv_hash_tuple(const BtorBitVectorTuple * t)3108 btor_bv_hash_tuple (const BtorBitVectorTuple *t)
3109 {
3110 assert (t);
3111
3112 uint32_t hash = 0;
3113 uint32_t i, j = 0;
3114
3115 for (i = 0; i < t->arity; i++)
3116 {
3117 assert (t->bv[i]);
3118 hash += btor_bv_hash (t->bv[i]) * hash_primes[j++];
3119 if (j == NPRIMES) j = 0;
3120 }
3121 return hash;
3122 }
3123
3124 BtorBitVectorTuple *
btor_bv_copy_tuple(BtorMemMgr * mm,BtorBitVectorTuple * t)3125 btor_bv_copy_tuple (BtorMemMgr *mm, BtorBitVectorTuple *t)
3126 {
3127 assert (mm);
3128 assert (t);
3129
3130 BtorBitVectorTuple *res = 0;
3131 uint32_t i;
3132
3133 res = btor_bv_new_tuple (mm, t->arity);
3134
3135 for (i = 0; i < t->arity; i++)
3136 {
3137 assert (t->bv[i]);
3138 res->bv[i] = btor_bv_copy (mm, t->bv[i]);
3139 }
3140 return res;
3141 }
3142
3143 size_t
btor_bv_size_tuple(BtorBitVectorTuple * t)3144 btor_bv_size_tuple (BtorBitVectorTuple *t)
3145 {
3146 assert (t);
3147
3148 uint32_t i;
3149 size_t res = 0;
3150
3151 res = sizeof (BtorBitVectorTuple) + t->arity * sizeof (BtorBitVector *);
3152 for (i = 0; i < t->arity; i++) res += btor_bv_size (t->bv[i]);
3153 return res;
3154 }
3155
3156 /*------------------------------------------------------------------------*/
3157