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