1 /*
2 * This file is part of the Yices SMT Solver.
3 * Copyright (C) 2017 SRI International.
4 *
5 * Yices is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Yices is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Yices. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 /*
20 * VARIABLE TABLE FOR BITVECTOR SOLVER
21 */
22
23 #include "solvers/bv/bv_vartable.h"
24 #include "terms/bv64_constants.h"
25 #include "terms/bv_constants.h"
26 #include "utils/hash_functions.h"
27 #include "utils/memalloc.h"
28
29
30 /*
31 * Initialize table
32 * - use the default size
33 * - the eterm array is not allocated here, but on the first
34 * call to attach_eterm
35 * - variable 0 is reserved to prevent confusion with const_idx
36 */
init_bv_vartable(bv_vartable_t * table)37 void init_bv_vartable(bv_vartable_t *table) {
38 uint32_t n;
39
40 n = DEF_BVVARTABLE_SIZE;
41 assert(1 <= n && n < MAX_BVVARTABLE_SIZE);
42
43 table->nvars = 1;
44 table->size = n;
45 table->bit_size = (uint32_t *) safe_malloc(n * sizeof(uint32_t));
46 table->kind = (uint8_t *) safe_malloc(n * sizeof(uint8_t));
47 table->def = (bvvar_desc_t *) safe_malloc(n * sizeof(bvvar_desc_t));
48 table->eterm = NULL;
49 table->map = (literal_t **) safe_malloc(n * sizeof(literal_t *));
50
51 // fake descriptor for variable 0
52 table->map[0] = NULL;
53 table->def[0].ptr = NULL;
54 table->kind[0] = BVTAG_VAR;
55 table->bit_size[0] = 0;
56
57 init_int_htbl(&table->htbl, 0);
58 }
59
60
61 /*
62 * Make the table 50% larger
63 */
extend_bv_vartable(bv_vartable_t * table)64 static void extend_bv_vartable(bv_vartable_t *table) {
65 uint32_t n;
66
67 n = table->size + 1;
68 n += n>>1;
69
70 if (n >= MAX_BVVARTABLE_SIZE) {
71 out_of_memory();
72 }
73
74 table->bit_size = (uint32_t *) safe_realloc(table->bit_size, n * sizeof(uint32_t));
75 table->kind = (uint8_t *) safe_realloc(table->kind, n * sizeof(uint8_t));
76 table->def = (bvvar_desc_t *) safe_realloc(table->def, n * sizeof(bvvar_desc_t));
77 if (table->eterm != NULL) {
78 table->eterm = (eterm_t *) safe_realloc(table->eterm, n * sizeof(eterm_t));
79 }
80 table->map = (literal_t **) safe_realloc(table->map, n * sizeof(literal_t *));
81
82 table->size = n;
83 }
84
85
86 /*
87 * Delete the table
88 */
delete_bv_vartable(bv_vartable_t * table)89 void delete_bv_vartable(bv_vartable_t *table) {
90 uint32_t i, n;
91
92 n = table->nvars;
93 for (i=1; i<n; i++) {
94 int_array_decref(table->map[i]);
95 switch (bvvar_tag(table, i)) {
96 case BVTAG_CONST:
97 case BVTAG_POLY64:
98 case BVTAG_PPROD:
99 case BVTAG_BIT_ARRAY:
100 case BVTAG_ITE:
101 safe_free(table->def[i].ptr);
102 break;
103
104 case BVTAG_POLY:
105 free_bvpoly(table->def[i].ptr);
106 break;
107
108 default:
109 break;
110 }
111 }
112
113 safe_free(table->bit_size);
114 safe_free(table->kind);
115 safe_free(table->def);
116 safe_free(table->eterm);
117 safe_free(table->map);
118
119 table->bit_size = NULL;
120 table->kind = NULL;
121 table->def = NULL;
122 table->eterm = NULL;
123 table->map = NULL;
124
125 delete_int_htbl(&table->htbl);
126 }
127
128
129 /*
130 * Reset: empty the table
131 */
reset_bv_vartable(bv_vartable_t * table)132 void reset_bv_vartable(bv_vartable_t *table) {
133 uint32_t i, n;
134
135 n = table->nvars;
136 for (i=1; i<n; i++) {
137 int_array_decref(table->map[i]);
138 switch (bvvar_tag(table, i)) {
139 case BVTAG_CONST:
140 case BVTAG_POLY64:
141 case BVTAG_PPROD:
142 case BVTAG_BIT_ARRAY:
143 case BVTAG_ITE:
144 safe_free(table->def[i].ptr);
145 break;
146
147 case BVTAG_POLY:
148 free_bvpoly(table->def[i].ptr);
149 break;
150
151 default:
152 break;
153 }
154 }
155
156 table->nvars = 1;
157
158 reset_int_htbl(&table->htbl);
159 }
160
161
162 /*
163 * Attach egraph term t to variable x
164 * - x must be not have an eterm attached already
165 */
attach_eterm_to_bvvar(bv_vartable_t * table,thvar_t x,eterm_t t)166 void attach_eterm_to_bvvar(bv_vartable_t *table, thvar_t x, eterm_t t) {
167 eterm_t *tmp;
168 uint32_t i, n;
169
170 assert(1 <= x && x < table->nvars && t != null_eterm);
171
172 tmp = table->eterm;
173 if (tmp == NULL) {
174 n = table->size;
175 tmp = (eterm_t *) safe_malloc(n * sizeof(eterm_t));
176 n = table->nvars;
177 for (i=0; i<n; i++) {
178 tmp[i] = null_eterm;
179 }
180 table->eterm = tmp;
181 }
182 assert(tmp[x] == null_eterm);
183 tmp[x] = t;
184 }
185
186
187
188
189 /*
190 * Remove all eterms of id >= nterms
191 */
bv_vartable_remove_eterms(bv_vartable_t * table,uint32_t nterms)192 void bv_vartable_remove_eterms(bv_vartable_t *table, uint32_t nterms) {
193 eterm_t *tmp;
194 uint32_t i, n;
195 eterm_t t;
196
197 tmp = table->eterm;
198
199 if (tmp != NULL) {
200 n = table->nvars;
201 for (i=1; i<n; i++) {
202 t = tmp[i];
203 if (t != null_eterm && t >= nterms) {
204 tmp[i] = null_eterm;
205 }
206 }
207 }
208 }
209
210
211
212 /*
213 * Hash codes of a variable descriptor
214 *
215 * For bvpoly and bvpoly64 we use
216 * hash_bvpoly (in bv_polynomials)
217 * hash_bvpoly64 (in bv64_polynomials)
218 *
219 */
220 // n = number of bits
hash_bvconst64(uint64_t c,uint32_t n)221 static inline uint32_t hash_bvconst64(uint64_t c, uint32_t n) {
222 uint32_t a, b;
223 a = jenkins_hash_uint64(c);
224 b = jenkins_hash_uint32(n);
225 return jenkins_hash_mix2(a, b);
226 }
227
hash_bvconst(uint32_t * c,uint32_t n)228 static inline uint32_t hash_bvconst(uint32_t *c, uint32_t n) {
229 return bvconst_hash(c, n);
230 }
231
232 // array of k pairs (variable, exponent)
hash_bvpprod_array(varexp_t * a,uint32_t k)233 static inline uint32_t hash_bvpprod_array(varexp_t *a, uint32_t k) {
234 assert(k <= UINT32_MAX/2);
235 return jenkins_hash_intarray((int32_t *) a, 2 * k);
236 }
237
hash_bvpprod(pprod_t * p)238 static inline uint32_t hash_bvpprod(pprod_t *p) {
239 return hash_bvpprod_array(p->prod, p->len);
240 }
241
hash_bvarray(literal_t * b,uint32_t n)242 static inline uint32_t hash_bvarray(literal_t *b, uint32_t n) {
243 return jenkins_hash_intarray2(b, n, 0xaed32b8);
244 }
245
hash_bvite(literal_t c,thvar_t x,thvar_t y)246 static inline uint32_t hash_bvite(literal_t c, thvar_t x, thvar_t y) {
247 return jenkins_hash_triple(c, x, y, 0xfe2efd45);
248 }
249
hash_bvite_ptr(bv_ite_t * d)250 static inline uint32_t hash_bvite_ptr(bv_ite_t *d) {
251 return hash_bvite(d->cond, d->left, d->right);
252 }
253
hash_bvdiv(thvar_t x,thvar_t y)254 static inline uint32_t hash_bvdiv(thvar_t x, thvar_t y) {
255 return jenkins_hash_pair(x, y, 0x2389a23f);
256 }
257
hash_bvrem(thvar_t x,thvar_t y)258 static inline uint32_t hash_bvrem(thvar_t x, thvar_t y) {
259 return jenkins_hash_pair(x, y, 0x237bc32f);
260 }
261
hash_bvsdiv(thvar_t x,thvar_t y)262 static inline uint32_t hash_bvsdiv(thvar_t x, thvar_t y) {
263 return jenkins_hash_pair(x, y, 0x9afe2ab2);
264 }
265
hash_bvsrem(thvar_t x,thvar_t y)266 static inline uint32_t hash_bvsrem(thvar_t x, thvar_t y) {
267 return jenkins_hash_pair(x, y, 0xbe7bca36);
268 }
269
hash_bvsmod(thvar_t x,thvar_t y)270 static inline uint32_t hash_bvsmod(thvar_t x, thvar_t y) {
271 return jenkins_hash_pair(x, y, 0xeab2d457);
272 }
273
hash_bvshl(thvar_t x,thvar_t y)274 static inline uint32_t hash_bvshl(thvar_t x, thvar_t y) {
275 return jenkins_hash_pair(x, y, 0xc2ad173f);
276 }
277
hash_bvlshr(thvar_t x,thvar_t y)278 static inline uint32_t hash_bvlshr(thvar_t x, thvar_t y) {
279 return jenkins_hash_pair(x, y, 0x81023ae5);
280 }
281
hash_bvashr(thvar_t x,thvar_t y)282 static inline uint32_t hash_bvashr(thvar_t x, thvar_t y) {
283 return jenkins_hash_pair(x, y, 0xc3e4fed1);
284 }
285
hash_bvadd(thvar_t x,thvar_t y)286 static inline uint32_t hash_bvadd(thvar_t x, thvar_t y) {
287 return jenkins_hash_pair(x, y, 0x198cea23);
288 }
289
hash_bvsub(thvar_t x,thvar_t y)290 static inline uint32_t hash_bvsub(thvar_t x, thvar_t y) {
291 return jenkins_hash_pair(x, y, 0xb8b423c6);
292 }
293
hash_bvmul(thvar_t x,thvar_t y)294 static inline uint32_t hash_bvmul(thvar_t x, thvar_t y) {
295 return jenkins_hash_pair(x, y, 0x43c94873);
296 }
297
hash_bvneg(thvar_t x)298 static inline uint32_t hash_bvneg(thvar_t x) {
299 return jenkins_hash_pair(x, x, 0x4b0d5cff);
300 }
301
302
303
304 /*
305 * Remove all variables of index >= nv
306 */
bv_vartable_remove_vars(bv_vartable_t * table,uint32_t nv)307 void bv_vartable_remove_vars(bv_vartable_t *table, uint32_t nv) {
308 uint32_t i, n, h;
309
310 assert(1 <= nv && nv <= table->nvars);
311
312 h = 0; // stop GCC warning
313
314 n = table->nvars;
315 for (i=nv; i<n; i++) {
316 switch (bvvar_tag(table, i)) {
317 case BVTAG_VAR:
318 // no hash consing, no descriptor
319 int_array_decref(table->map[i]);
320 continue;
321
322 case BVTAG_CONST64:
323 h = hash_bvconst64(table->def[i].val, table->bit_size[i]);
324 break;
325
326 case BVTAG_CONST:
327 h = hash_bvconst(table->def[i].ptr, table->bit_size[i]);
328 safe_free(table->def[i].ptr);
329 break;
330
331 case BVTAG_POLY64:
332 h = hash_bvpoly64(table->def[i].ptr);
333 safe_free(table->def[i].ptr);
334 break;
335
336 case BVTAG_POLY:
337 h = hash_bvpoly(table->def[i].ptr);
338 free_bvpoly(table->def[i].ptr);
339 break;
340
341 case BVTAG_PPROD:
342 h = hash_bvpprod(table->def[i].ptr);
343 safe_free(table->def[i].ptr);
344 break;
345
346 case BVTAG_BIT_ARRAY:
347 h = hash_bvarray(table->def[i].ptr, table->bit_size[i]);
348 safe_free(table->def[i].ptr);
349 break;
350
351 case BVTAG_ITE:
352 h = hash_bvite_ptr(table->def[i].ptr);
353 safe_free(table->def[i].ptr);
354 break;
355
356 case BVTAG_UDIV:
357 h = hash_bvdiv(table->def[i].op[0], table->def[i].op[1]);
358 break;
359
360 case BVTAG_UREM:
361 h = hash_bvrem(table->def[i].op[0], table->def[i].op[1]);
362 break;
363
364 case BVTAG_SDIV:
365 h = hash_bvsdiv(table->def[i].op[0], table->def[i].op[1]);
366 break;
367
368 case BVTAG_SREM:
369 h = hash_bvsrem(table->def[i].op[0], table->def[i].op[1]);
370 break;
371
372 case BVTAG_SMOD:
373 h = hash_bvsmod(table->def[i].op[0], table->def[i].op[1]);
374 break;
375
376 case BVTAG_SHL:
377 h = hash_bvshl(table->def[i].op[0], table->def[i].op[1]);
378 break;
379
380 case BVTAG_LSHR:
381 h = hash_bvlshr(table->def[i].op[0], table->def[i].op[1]);
382 break;
383
384 case BVTAG_ASHR:
385 h = hash_bvashr(table->def[i].op[0], table->def[i].op[1]);
386 break;
387
388 case BVTAG_ADD:
389 h = hash_bvadd(table->def[i].op[0], table->def[i].op[1]);
390 break;
391
392 case BVTAG_SUB:
393 h = hash_bvsub(table->def[i].op[0], table->def[i].op[1]);
394 break;
395
396 case BVTAG_MUL:
397 h = hash_bvmul(table->def[i].op[0], table->def[i].op[1]);
398 break;
399
400 case BVTAG_NEG:
401 h = hash_bvneg(table->def[i].op[0]);
402 break;
403 }
404
405 int_htbl_erase_record(&table->htbl, h, i);
406 int_array_decref(table->map[i]);
407 }
408
409 table->nvars = nv;
410 }
411
412
413
414 /*
415 * Allocate a new variable id of n bits
416 * - the descriptors are partially initialized:
417 * bit_size = n
418 * eterm = null_eterm if table->eterm exists
419 * map = NULL
420 * - def and kind are not set
421 */
bv_vartable_alloc_id(bv_vartable_t * table,uint32_t n)422 static thvar_t bv_vartable_alloc_id(bv_vartable_t *table, uint32_t n) {
423 uint32_t x;
424
425 x = table->nvars;
426 if (x == table->size) {
427 extend_bv_vartable(table);
428 }
429 assert(x < table->size);
430 table->bit_size[x] = n;
431 table->map[x] = NULL;
432 if (table->eterm != NULL) {
433 table->eterm[x] = null_eterm;
434 }
435
436 table->nvars = x + 1;
437
438 return x;
439 }
440
441
442
443 /*
444 * Constructors:
445 * - all constructors create a new theory variable with the given definition
446 * - when present n = bitsize of the new variable
447 */
make_bvvar(bv_vartable_t * table,uint32_t n)448 thvar_t make_bvvar(bv_vartable_t *table, uint32_t n) {
449 thvar_t x;
450
451 x = bv_vartable_alloc_id(table, n);
452 table->kind[x] = BVTAG_VAR;
453
454 return x;
455 }
456
make_bvconst64(bv_vartable_t * table,uint32_t n,uint64_t val)457 static thvar_t make_bvconst64(bv_vartable_t *table, uint32_t n, uint64_t val) {
458 thvar_t x;
459
460 assert(norm64(val, n) == val);
461 x = bv_vartable_alloc_id(table, n);
462 table->kind[x] = BVTAG_CONST64;
463 table->def[x].val = val;
464
465 return x;
466 }
467
make_bvconst(bv_vartable_t * table,uint32_t n,uint32_t * val)468 static thvar_t make_bvconst(bv_vartable_t *table, uint32_t n, uint32_t *val) {
469 uint32_t *tmp;
470 thvar_t x;
471 uint32_t w;
472
473 // make a copy of val
474 w = (n + 31) >> 5;
475 tmp = (uint32_t *) safe_malloc(w * sizeof(uint32_t));
476 bvconst_set(tmp, w, val);
477 bvconst_normalize(tmp, n);
478
479 x = bv_vartable_alloc_id(table, n);
480 table->kind[x] = BVTAG_CONST;
481 table->def[x].ptr = tmp;
482
483 return x;
484 }
485
make_bvpoly64(bv_vartable_t * table,bvpoly_buffer_t * b)486 static thvar_t make_bvpoly64(bv_vartable_t *table, bvpoly_buffer_t *b) {
487 thvar_t x;
488
489 x = bv_vartable_alloc_id(table, b->bitsize);
490 table->kind[x] = BVTAG_POLY64;
491 table->def[x].ptr = bvpoly_buffer_getpoly64(b);
492
493 return x;
494 }
495
make_bvpoly(bv_vartable_t * table,bvpoly_buffer_t * b)496 static thvar_t make_bvpoly(bv_vartable_t *table, bvpoly_buffer_t *b) {
497 thvar_t x;
498
499 x = bv_vartable_alloc_id(table, b->bitsize);
500 table->kind[x] = BVTAG_POLY;
501 table->def[x].ptr = bvpoly_buffer_getpoly(b);
502
503 return x;
504 }
505
make_bvpprod(bv_vartable_t * table,uint32_t n,pp_buffer_t * b)506 static thvar_t make_bvpprod(bv_vartable_t *table, uint32_t n, pp_buffer_t *b) {
507 thvar_t x;
508
509 x = bv_vartable_alloc_id(table, n);
510 table->kind[x] = BVTAG_PPROD;
511 table->def[x].ptr = pp_buffer_getprod(b);
512
513 return x;
514 }
515
make_bvarray(bv_vartable_t * table,uint32_t n,literal_t * a)516 static thvar_t make_bvarray(bv_vartable_t *table, uint32_t n, literal_t *a) {
517 literal_t *b;
518 uint32_t i;
519 thvar_t x;
520
521 // make a copy of a
522 b = (literal_t *) safe_malloc(n * sizeof(literal_t));
523 for (i=0; i<n; i++) {
524 b[i] = a[i];
525 }
526
527 x = bv_vartable_alloc_id(table, n);
528 table->kind[x] = BVTAG_BIT_ARRAY;
529 table->def[x].ptr = b;
530
531 return x;
532 }
533
make_bvite(bv_vartable_t * table,uint32_t n,literal_t c,thvar_t left,thvar_t right)534 static thvar_t make_bvite(bv_vartable_t *table, uint32_t n, literal_t c, thvar_t left, thvar_t right) {
535 bv_ite_t *b;
536 thvar_t x;
537
538 b = (bv_ite_t *) safe_malloc(sizeof(bv_ite_t));
539 b->cond = c;
540 b->left = left;
541 b->right = right;
542
543 x = bv_vartable_alloc_id(table, n);
544 table->kind[x] = BVTAG_ITE;
545 table->def[x].ptr = b;
546
547 return x;
548 }
549
550
551 // binary operator: tag must be in BVTAG_UDIV ... BVTAG_ASHR
make_bvbinop(bv_vartable_t * table,bvvar_tag_t tag,uint32_t n,thvar_t x,thvar_t y)552 static thvar_t make_bvbinop(bv_vartable_t *table, bvvar_tag_t tag, uint32_t n, thvar_t x, thvar_t y) {
553 thvar_t z;
554
555 z = bv_vartable_alloc_id(table, n);
556 table->kind[z] = tag;
557 table->def[z].op[0] = x;
558 table->def[z].op[1] = y;
559
560 return z;
561 }
562
563
564
565 /*
566 * HASH CONSING OBJECTS (cf. int_hash_tables)
567 */
568 typedef struct bvconst64_hobj_s {
569 int_hobj_t m;
570 bv_vartable_t *tbl;
571 uint64_t val;
572 uint32_t nbits;
573 } bvconst64_hobj_t;
574
575 typedef struct bvconst_hobj_s {
576 int_hobj_t m;
577 bv_vartable_t *tbl;
578 uint32_t *val;
579 uint32_t nbits;
580 } bvconst_hobj_t;
581
582 typedef struct bvpoly_hobj_s {
583 int_hobj_t m;
584 bv_vartable_t *tbl;
585 bvpoly_buffer_t *buffer;
586 } bvpoly_hobj_t;
587
588 typedef struct bvpprod_hobj_s {
589 int_hobj_t m;
590 bv_vartable_t *tbl;
591 pp_buffer_t *buffer;
592 uint32_t nbits;
593 } bvpprod_hobj_t;
594
595 typedef struct bvarray_hobj_s {
596 int_hobj_t m;
597 bv_vartable_t *tbl;
598 literal_t *val;
599 uint32_t nbits;
600 } bvarray_hobj_t;
601
602 typedef struct bvite_hobj_s {
603 int_hobj_t m;
604 bv_vartable_t *tbl;
605 literal_t cond;
606 thvar_t left;
607 thvar_t right;
608 uint32_t nbits;
609 } bvite_hobj_t;
610
611 // for all binary constructors
612 typedef struct bvop_hobj_s {
613 int_hobj_t m;
614 bv_vartable_t *tbl;
615 thvar_t left;
616 thvar_t right;
617 uint32_t nbits;
618 } bvop_hobj_t;
619
620
621 /*
622 * Hash functions
623 */
hash_bvconst64_hobj(bvconst64_hobj_t * p)624 static uint32_t hash_bvconst64_hobj(bvconst64_hobj_t *p) {
625 return hash_bvconst64(p->val, p->nbits);
626 }
627
hash_bvconst_hobj(bvconst_hobj_t * p)628 static uint32_t hash_bvconst_hobj(bvconst_hobj_t *p) {
629 return hash_bvconst(p->val, p->nbits);
630 }
631
hash_bvpoly64_hobj(bvpoly_hobj_t * p)632 static uint32_t hash_bvpoly64_hobj(bvpoly_hobj_t *p) {
633 return bvpoly_buffer_hash64(p->buffer);
634 }
635
hash_bvpoly_hobj(bvpoly_hobj_t * p)636 static uint32_t hash_bvpoly_hobj(bvpoly_hobj_t *p) {
637 return bvpoly_buffer_hash(p->buffer);
638 }
639
hash_bvpprod_hobj(bvpprod_hobj_t * p)640 static uint32_t hash_bvpprod_hobj(bvpprod_hobj_t *p) {
641 pp_buffer_t *b;
642
643 b = p->buffer;
644 return hash_bvpprod_array(b->prod, b->len);
645 }
646
hash_bvarray_hobj(bvarray_hobj_t * p)647 static uint32_t hash_bvarray_hobj(bvarray_hobj_t *p) {
648 return hash_bvarray(p->val, p->nbits);
649 }
650
hash_bvite_hobj(bvite_hobj_t * p)651 static uint32_t hash_bvite_hobj(bvite_hobj_t *p) {
652 return hash_bvite(p->cond, p->left, p->right);
653 }
654
hash_bvdiv_hobj(bvop_hobj_t * p)655 static uint32_t hash_bvdiv_hobj(bvop_hobj_t *p) {
656 return hash_bvdiv(p->left, p->right);
657 }
658
hash_bvrem_hobj(bvop_hobj_t * p)659 static uint32_t hash_bvrem_hobj(bvop_hobj_t *p) {
660 return hash_bvrem(p->left, p->right);
661 }
662
hash_bvsdiv_hobj(bvop_hobj_t * p)663 static uint32_t hash_bvsdiv_hobj(bvop_hobj_t *p) {
664 return hash_bvsdiv(p->left, p->right);
665 }
666
hash_bvsrem_hobj(bvop_hobj_t * p)667 static uint32_t hash_bvsrem_hobj(bvop_hobj_t *p) {
668 return hash_bvsrem(p->left, p->right);
669 }
670
hash_bvsmod_hobj(bvop_hobj_t * p)671 static uint32_t hash_bvsmod_hobj(bvop_hobj_t *p) {
672 return hash_bvsmod(p->left, p->right);
673 }
674
hash_bvshl_hobj(bvop_hobj_t * p)675 static uint32_t hash_bvshl_hobj(bvop_hobj_t *p) {
676 return hash_bvshl(p->left, p->right);
677 }
678
hash_bvlshr_hobj(bvop_hobj_t * p)679 static uint32_t hash_bvlshr_hobj(bvop_hobj_t *p) {
680 return hash_bvlshr(p->left, p->right);
681 }
682
hash_bvashr_hobj(bvop_hobj_t * p)683 static uint32_t hash_bvashr_hobj(bvop_hobj_t *p) {
684 return hash_bvashr(p->left, p->right);
685 }
686
hash_bvadd_hobj(bvop_hobj_t * p)687 static uint32_t hash_bvadd_hobj(bvop_hobj_t *p) {
688 return hash_bvadd(p->left, p->right);
689 }
690
hash_bvsub_hobj(bvop_hobj_t * p)691 static uint32_t hash_bvsub_hobj(bvop_hobj_t *p) {
692 return hash_bvsub(p->left, p->right);
693 }
694
hash_bvmul_hobj(bvop_hobj_t * p)695 static uint32_t hash_bvmul_hobj(bvop_hobj_t *p) {
696 return hash_bvmul(p->left, p->right);
697 }
698
hash_bvneg_hobj(bvop_hobj_t * p)699 static uint32_t hash_bvneg_hobj(bvop_hobj_t *p) {
700 return hash_bvneg(p->left);
701 }
702
703
704
705 /*
706 * Equality tests
707 */
eq_bvconst64_hobj(bvconst64_hobj_t * p,thvar_t i)708 static bool eq_bvconst64_hobj(bvconst64_hobj_t *p, thvar_t i) {
709 bv_vartable_t *table;
710
711 table = p->tbl;
712 return bvvar_tag(table, i) == BVTAG_CONST64 &&
713 table->bit_size[i] == p->nbits && table->def[i].val == p->val;
714 }
715
eq_bvconst_hobj(bvconst_hobj_t * p,thvar_t i)716 static bool eq_bvconst_hobj(bvconst_hobj_t *p, thvar_t i) {
717 bv_vartable_t *table;
718 uint32_t w;
719
720 table = p->tbl;
721 if (bvvar_tag(table, i) != BVTAG_CONST || table->bit_size[i] != p->nbits) {
722 return false;
723 }
724 w = (p->nbits + 31) >> 5;
725 return bvconst_eq(p->val, table->def[i].ptr, w);
726 }
727
eq_bvpoly64_hobj(bvpoly_hobj_t * p,thvar_t i)728 static bool eq_bvpoly64_hobj(bvpoly_hobj_t *p, thvar_t i) {
729 bv_vartable_t *table;
730
731 table = p->tbl;
732 return bvvar_tag(table, i) == BVTAG_POLY64 &&
733 bvpoly_buffer_equal_poly64(p->buffer, table->def[i].ptr);
734 }
735
eq_bvpoly_hobj(bvpoly_hobj_t * p,thvar_t i)736 static bool eq_bvpoly_hobj(bvpoly_hobj_t *p, thvar_t i) {
737 bv_vartable_t *table;
738
739 table = p->tbl;
740 return bvvar_tag(table, i) == BVTAG_POLY &&
741 bvpoly_buffer_equal_poly(p->buffer, table->def[i].ptr);
742 }
743
744
745 // helper function
pp_buffer_eq_pprod(pp_buffer_t * buffer,pprod_t * p)746 static bool pp_buffer_eq_pprod(pp_buffer_t *buffer, pprod_t *p) {
747 uint32_t n;
748
749 n = buffer->len;
750 return p->len == n && varexp_array_equal(buffer->prod, p->prod, n);
751 }
752
eq_bvpprod_hobj(bvpprod_hobj_t * p,thvar_t i)753 static bool eq_bvpprod_hobj(bvpprod_hobj_t *p, thvar_t i) {
754 bv_vartable_t *table;
755
756 table = p->tbl;
757 return bvvar_tag(table, i) == BVTAG_PPROD &&
758 pp_buffer_eq_pprod(p->buffer, table->def[i].ptr);
759 }
760
761
eq_bvarray_hobj(bvarray_hobj_t * p,thvar_t i)762 static bool eq_bvarray_hobj(bvarray_hobj_t *p, thvar_t i) {
763 bv_vartable_t *table;
764 literal_t *a;
765 uint32_t j, n;
766
767 table = p->tbl;
768 n = p->nbits;
769 if (bvvar_tag(table, i) != BVTAG_BIT_ARRAY || table->bit_size[i] != n) {
770 return false;
771 }
772
773 a = table->def[i].ptr;
774 for (j=0; j<n; j++) {
775 if (a[j] != p->val[j]) return false;
776 }
777
778 return true;
779 }
780
eq_bvite_hobj(bvite_hobj_t * p,thvar_t i)781 static bool eq_bvite_hobj(bvite_hobj_t *p, thvar_t i) {
782 bv_vartable_t *table;
783 bv_ite_t *d;
784
785 table = p->tbl;
786 if (bvvar_tag(table, i) == BVTAG_ITE) {
787 d = table->def[i].ptr;
788 return d->cond == p->cond && d->left == p->left && d->right == p->right;
789 } else {
790 return false;
791 }
792 }
793
eq_bvdiv_hobj(bvop_hobj_t * p,thvar_t i)794 static bool eq_bvdiv_hobj(bvop_hobj_t *p, thvar_t i) {
795 bv_vartable_t *table;
796
797 table = p->tbl;
798 return bvvar_tag(table, i) == BVTAG_UDIV && table->def[i].op[0] == p->left &&
799 table->def[i].op[1] == p->right;
800 }
801
eq_bvrem_hobj(bvop_hobj_t * p,thvar_t i)802 static bool eq_bvrem_hobj(bvop_hobj_t *p, thvar_t i) {
803 bv_vartable_t *table;
804
805 table = p->tbl;
806 return bvvar_tag(table, i) == BVTAG_UREM && table->def[i].op[0] == p->left &&
807 table->def[i].op[1] == p->right;
808 }
809
eq_bvsdiv_hobj(bvop_hobj_t * p,thvar_t i)810 static bool eq_bvsdiv_hobj(bvop_hobj_t *p, thvar_t i) {
811 bv_vartable_t *table;
812
813 table = p->tbl;
814 return bvvar_tag(table, i) == BVTAG_SDIV && table->def[i].op[0] == p->left &&
815 table->def[i].op[1] == p->right;
816 }
817
eq_bvsrem_hobj(bvop_hobj_t * p,thvar_t i)818 static bool eq_bvsrem_hobj(bvop_hobj_t *p, thvar_t i) {
819 bv_vartable_t *table;
820
821 table = p->tbl;
822 return bvvar_tag(table, i) == BVTAG_SREM && table->def[i].op[0] == p->left &&
823 table->def[i].op[1] == p->right;
824 }
825
eq_bvsmod_hobj(bvop_hobj_t * p,thvar_t i)826 static bool eq_bvsmod_hobj(bvop_hobj_t *p, thvar_t i) {
827 bv_vartable_t *table;
828
829 table = p->tbl;
830 return bvvar_tag(table, i) == BVTAG_SMOD && table->def[i].op[0] == p->left &&
831 table->def[i].op[1] == p->right;
832 }
833
eq_bvshl_hobj(bvop_hobj_t * p,thvar_t i)834 static bool eq_bvshl_hobj(bvop_hobj_t *p, thvar_t i) {
835 bv_vartable_t *table;
836
837 table = p->tbl;
838 return bvvar_tag(table, i) == BVTAG_SHL && table->def[i].op[0] == p->left &&
839 table->def[i].op[1] == p->right;
840 }
841
eq_bvlshr_hobj(bvop_hobj_t * p,thvar_t i)842 static bool eq_bvlshr_hobj(bvop_hobj_t *p, thvar_t i) {
843 bv_vartable_t *table;
844
845 table = p->tbl;
846 return bvvar_tag(table, i) == BVTAG_LSHR && table->def[i].op[0] == p->left &&
847 table->def[i].op[1] == p->right;
848 }
849
eq_bvashr_hobj(bvop_hobj_t * p,thvar_t i)850 static bool eq_bvashr_hobj(bvop_hobj_t *p, thvar_t i) {
851 bv_vartable_t *table;
852
853 table = p->tbl;
854 return bvvar_tag(table, i) == BVTAG_ASHR && table->def[i].op[0] == p->left &&
855 table->def[i].op[1] == p->right;
856 }
857
858
eq_bvadd_hobj(bvop_hobj_t * p,thvar_t i)859 static bool eq_bvadd_hobj(bvop_hobj_t *p, thvar_t i) {
860 bv_vartable_t *table;
861
862 table = p->tbl;
863 return bvvar_tag(table, i) == BVTAG_ADD && table->def[i].op[0] == p->left &&
864 table->def[i].op[1] == p->right;
865 }
866
eq_bvsub_hobj(bvop_hobj_t * p,thvar_t i)867 static bool eq_bvsub_hobj(bvop_hobj_t *p, thvar_t i) {
868 bv_vartable_t *table;
869
870 table = p->tbl;
871 return bvvar_tag(table, i) == BVTAG_SUB && table->def[i].op[0] == p->left &&
872 table->def[i].op[1] == p->right;
873 }
874
eq_bvmul_hobj(bvop_hobj_t * p,thvar_t i)875 static bool eq_bvmul_hobj(bvop_hobj_t *p, thvar_t i) {
876 bv_vartable_t *table;
877
878 table = p->tbl;
879 return bvvar_tag(table, i) == BVTAG_MUL && table->def[i].op[0] == p->left &&
880 table->def[i].op[1] == p->right;
881 }
882
eq_bvneg_hobj(bvop_hobj_t * p,thvar_t i)883 static bool eq_bvneg_hobj(bvop_hobj_t *p, thvar_t i) {
884 bv_vartable_t *table;
885
886 table = p->tbl;
887 return bvvar_tag(table, i) == BVTAG_NEG && table->def[i].op[0] == p->left;
888 }
889
890
891
892
893
894 /*
895 * Build
896 */
build_bvconst64_hobj(bvconst64_hobj_t * p)897 static thvar_t build_bvconst64_hobj(bvconst64_hobj_t *p) {
898 return make_bvconst64(p->tbl, p->nbits, p->val);
899 }
900
build_bvconst_hobj(bvconst_hobj_t * p)901 static thvar_t build_bvconst_hobj(bvconst_hobj_t *p) {
902 return make_bvconst(p->tbl, p->nbits, p->val);
903 }
904
build_bvpoly64_hobj(bvpoly_hobj_t * p)905 static thvar_t build_bvpoly64_hobj(bvpoly_hobj_t *p) {
906 return make_bvpoly64(p->tbl, p->buffer);
907 }
908
build_bvpoly_hobj(bvpoly_hobj_t * p)909 static thvar_t build_bvpoly_hobj(bvpoly_hobj_t *p) {
910 return make_bvpoly(p->tbl, p->buffer);
911 }
912
build_bvpprod_hobj(bvpprod_hobj_t * p)913 static thvar_t build_bvpprod_hobj(bvpprod_hobj_t *p) {
914 return make_bvpprod(p->tbl, p->nbits, p->buffer);
915 }
916
build_bvarray_hobj(bvarray_hobj_t * p)917 static thvar_t build_bvarray_hobj(bvarray_hobj_t *p) {
918 return make_bvarray(p->tbl, p->nbits, p->val);
919 }
920
build_bvite_hobj(bvite_hobj_t * p)921 static thvar_t build_bvite_hobj(bvite_hobj_t *p) {
922 return make_bvite(p->tbl, p->nbits, p->cond, p->left, p->right);
923 }
924
build_bvdiv_hobj(bvop_hobj_t * p)925 static thvar_t build_bvdiv_hobj(bvop_hobj_t *p) {
926 return make_bvbinop(p->tbl, BVTAG_UDIV, p->nbits, p->left, p->right);
927 }
928
build_bvrem_hobj(bvop_hobj_t * p)929 static thvar_t build_bvrem_hobj(bvop_hobj_t *p) {
930 return make_bvbinop(p->tbl, BVTAG_UREM, p->nbits, p->left, p->right);
931 }
932
build_bvsdiv_hobj(bvop_hobj_t * p)933 static thvar_t build_bvsdiv_hobj(bvop_hobj_t *p) {
934 return make_bvbinop(p->tbl, BVTAG_SDIV, p->nbits, p->left, p->right);
935 }
936
build_bvsrem_hobj(bvop_hobj_t * p)937 static thvar_t build_bvsrem_hobj(bvop_hobj_t *p) {
938 return make_bvbinop(p->tbl, BVTAG_SREM, p->nbits, p->left, p->right);
939 }
940
build_bvsmod_hobj(bvop_hobj_t * p)941 static thvar_t build_bvsmod_hobj(bvop_hobj_t *p) {
942 return make_bvbinop(p->tbl, BVTAG_SMOD, p->nbits, p->left, p->right);
943 }
944
build_bvshl_hobj(bvop_hobj_t * p)945 static thvar_t build_bvshl_hobj(bvop_hobj_t *p) {
946 return make_bvbinop(p->tbl, BVTAG_SHL, p->nbits, p->left, p->right);
947 }
948
build_bvlshr_hobj(bvop_hobj_t * p)949 static thvar_t build_bvlshr_hobj(bvop_hobj_t *p) {
950 return make_bvbinop(p->tbl, BVTAG_LSHR, p->nbits, p->left, p->right);
951 }
952
build_bvashr_hobj(bvop_hobj_t * p)953 static thvar_t build_bvashr_hobj(bvop_hobj_t *p) {
954 return make_bvbinop(p->tbl, BVTAG_ASHR, p->nbits, p->left, p->right);
955 }
956
build_bvadd_hobj(bvop_hobj_t * p)957 static thvar_t build_bvadd_hobj(bvop_hobj_t *p) {
958 return make_bvbinop(p->tbl, BVTAG_ADD, p->nbits, p->left, p->right);
959 }
960
build_bvsub_hobj(bvop_hobj_t * p)961 static thvar_t build_bvsub_hobj(bvop_hobj_t *p) {
962 return make_bvbinop(p->tbl, BVTAG_SUB, p->nbits, p->left, p->right);
963 }
964
build_bvmul_hobj(bvop_hobj_t * p)965 static thvar_t build_bvmul_hobj(bvop_hobj_t *p) {
966 return make_bvbinop(p->tbl, BVTAG_MUL, p->nbits, p->left, p->right);
967 }
968
build_bvneg_hobj(bvop_hobj_t * p)969 static thvar_t build_bvneg_hobj(bvop_hobj_t *p) {
970 return make_bvbinop(p->tbl, BVTAG_NEG, p->nbits, p->left, null_thvar);
971 }
972
973
974 /*
975 * Hash-consing constructors
976 */
get_bvconst64(bv_vartable_t * table,uint32_t n,uint64_t val)977 thvar_t get_bvconst64(bv_vartable_t *table, uint32_t n, uint64_t val) {
978 bvconst64_hobj_t bvconst64_hobj;
979
980 bvconst64_hobj.m.hash = (hobj_hash_t) hash_bvconst64_hobj;
981 bvconst64_hobj.m.eq = (hobj_eq_t) eq_bvconst64_hobj;
982 bvconst64_hobj.m.build = (hobj_build_t) build_bvconst64_hobj;
983 bvconst64_hobj.tbl = table;
984 bvconst64_hobj.val = val;
985 bvconst64_hobj.nbits = n;
986 return int_htbl_get_obj(&table->htbl, &bvconst64_hobj.m);
987 }
988
get_bvconst(bv_vartable_t * table,uint32_t n,uint32_t * val)989 thvar_t get_bvconst(bv_vartable_t *table, uint32_t n, uint32_t *val) {
990 bvconst_hobj_t bvconst_hobj;
991
992 bvconst_hobj.m.hash = (hobj_hash_t) hash_bvconst_hobj;
993 bvconst_hobj.m.eq = (hobj_eq_t) eq_bvconst_hobj;
994 bvconst_hobj.m.build = (hobj_build_t) build_bvconst_hobj;
995 bvconst_hobj.tbl = table;
996 bvconst_hobj.val = val;
997 bvconst_hobj.nbits = n;
998 return int_htbl_get_obj(&table->htbl, &bvconst_hobj.m);
999 }
1000
get_bvpoly64(bv_vartable_t * table,bvpoly_buffer_t * buffer)1001 thvar_t get_bvpoly64(bv_vartable_t *table, bvpoly_buffer_t *buffer) {
1002 bvpoly_hobj_t bvpoly64_hobj;
1003
1004 bvpoly64_hobj.m.hash = (hobj_hash_t) hash_bvpoly64_hobj;
1005 bvpoly64_hobj.m.eq = (hobj_eq_t) eq_bvpoly64_hobj;
1006 bvpoly64_hobj.m.build = (hobj_build_t) build_bvpoly64_hobj;
1007 bvpoly64_hobj.tbl = table;
1008 bvpoly64_hobj.buffer = buffer;
1009 return int_htbl_get_obj(&table->htbl, &bvpoly64_hobj.m);
1010 }
1011
get_bvpoly(bv_vartable_t * table,bvpoly_buffer_t * buffer)1012 thvar_t get_bvpoly(bv_vartable_t *table, bvpoly_buffer_t *buffer) {
1013 bvpoly_hobj_t bvpoly_hobj;
1014
1015 bvpoly_hobj.m.hash = (hobj_hash_t) hash_bvpoly_hobj;
1016 bvpoly_hobj.m.eq = (hobj_eq_t) eq_bvpoly_hobj;
1017 bvpoly_hobj.m.build = (hobj_build_t) build_bvpoly_hobj;
1018 bvpoly_hobj.tbl = table;
1019 bvpoly_hobj.buffer = buffer;
1020 return int_htbl_get_obj(&table->htbl, &bvpoly_hobj.m);
1021 }
1022
get_bvpprod(bv_vartable_t * table,uint32_t n,pp_buffer_t * buffer)1023 thvar_t get_bvpprod(bv_vartable_t *table, uint32_t n, pp_buffer_t *buffer) {
1024 bvpprod_hobj_t bvpprod_hobj;
1025
1026 bvpprod_hobj.m.hash = (hobj_hash_t) hash_bvpprod_hobj;
1027 bvpprod_hobj.m.eq = (hobj_eq_t) eq_bvpprod_hobj;
1028 bvpprod_hobj.m.build = (hobj_build_t) build_bvpprod_hobj;
1029 bvpprod_hobj.tbl = table;
1030 bvpprod_hobj.buffer = buffer;
1031 bvpprod_hobj.nbits = n;
1032 return int_htbl_get_obj(&table->htbl, &bvpprod_hobj.m);
1033 }
1034
get_bvarray(bv_vartable_t * table,uint32_t n,literal_t * a)1035 thvar_t get_bvarray(bv_vartable_t *table, uint32_t n, literal_t *a) {
1036 bvarray_hobj_t bvarray_hobj;
1037
1038 bvarray_hobj.m.hash = (hobj_hash_t) hash_bvarray_hobj;
1039 bvarray_hobj.m.eq = (hobj_eq_t) eq_bvarray_hobj;
1040 bvarray_hobj.m.build = (hobj_build_t) build_bvarray_hobj;
1041 bvarray_hobj.tbl = table;
1042 bvarray_hobj.val = a;
1043 bvarray_hobj.nbits = n;
1044 return int_htbl_get_obj(&table->htbl, &bvarray_hobj.m);
1045 }
1046
get_bvite(bv_vartable_t * table,uint32_t n,literal_t l,thvar_t x,thvar_t y)1047 thvar_t get_bvite(bv_vartable_t *table, uint32_t n, literal_t l, thvar_t x, thvar_t y) {
1048 bvite_hobj_t bvite_hobj;
1049
1050 bvite_hobj.m.hash = (hobj_hash_t) hash_bvite_hobj;
1051 bvite_hobj.m.eq = (hobj_eq_t) eq_bvite_hobj;
1052 bvite_hobj.m.build = (hobj_build_t) build_bvite_hobj;
1053 bvite_hobj.tbl = table;
1054 bvite_hobj.cond = l;
1055 bvite_hobj.left = x;
1056 bvite_hobj.right = y;
1057 bvite_hobj.nbits = n;
1058 return int_htbl_get_obj(&table->htbl, &bvite_hobj.m);
1059 }
1060
get_bvdiv(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1061 thvar_t get_bvdiv(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1062 bvop_hobj_t bvdiv_hobj;
1063
1064 bvdiv_hobj.m.hash = (hobj_hash_t) hash_bvdiv_hobj;
1065 bvdiv_hobj.m.eq = (hobj_eq_t) eq_bvdiv_hobj;
1066 bvdiv_hobj.m.build = (hobj_build_t) build_bvdiv_hobj;
1067 bvdiv_hobj.tbl = table;
1068 bvdiv_hobj.left = x;
1069 bvdiv_hobj.right = y;
1070 bvdiv_hobj.nbits = n;
1071 return int_htbl_get_obj(&table->htbl, &bvdiv_hobj.m);
1072 }
1073
get_bvrem(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1074 thvar_t get_bvrem(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1075 bvop_hobj_t bvrem_hobj;
1076
1077 bvrem_hobj.m.hash = (hobj_hash_t) hash_bvrem_hobj;
1078 bvrem_hobj.m.eq = (hobj_eq_t) eq_bvrem_hobj;
1079 bvrem_hobj.m.build = (hobj_build_t) build_bvrem_hobj;
1080 bvrem_hobj.tbl = table;
1081 bvrem_hobj.left = x;
1082 bvrem_hobj.right = y;
1083 bvrem_hobj.nbits = n;
1084 return int_htbl_get_obj(&table->htbl, &bvrem_hobj.m);
1085 }
1086
get_bvsdiv(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1087 thvar_t get_bvsdiv(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1088 bvop_hobj_t bvsdiv_hobj;
1089
1090 bvsdiv_hobj.m.hash = (hobj_hash_t) hash_bvsdiv_hobj;
1091 bvsdiv_hobj.m.eq = (hobj_eq_t) eq_bvsdiv_hobj;
1092 bvsdiv_hobj.m.build = (hobj_build_t) build_bvsdiv_hobj;
1093 bvsdiv_hobj.tbl = table;
1094 bvsdiv_hobj.left = x;
1095 bvsdiv_hobj.right = y;
1096 bvsdiv_hobj.nbits = n;
1097 return int_htbl_get_obj(&table->htbl, &bvsdiv_hobj.m);
1098 }
1099
get_bvsrem(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1100 thvar_t get_bvsrem(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1101 bvop_hobj_t bvsrem_hobj;
1102
1103 bvsrem_hobj.m.hash = (hobj_hash_t) hash_bvsrem_hobj;
1104 bvsrem_hobj.m.eq = (hobj_eq_t) eq_bvsrem_hobj;
1105 bvsrem_hobj.m.build = (hobj_build_t) build_bvsrem_hobj;
1106 bvsrem_hobj.tbl = table;
1107 bvsrem_hobj.left = x;
1108 bvsrem_hobj.right = y;
1109 bvsrem_hobj.nbits = n;
1110 return int_htbl_get_obj(&table->htbl, &bvsrem_hobj.m);
1111 }
1112
get_bvsmod(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1113 thvar_t get_bvsmod(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1114 bvop_hobj_t bvsmod_hobj;
1115
1116 bvsmod_hobj.m.hash = (hobj_hash_t) hash_bvsmod_hobj;
1117 bvsmod_hobj.m.eq = (hobj_eq_t) eq_bvsmod_hobj;
1118 bvsmod_hobj.m.build = (hobj_build_t) build_bvsmod_hobj;
1119 bvsmod_hobj.tbl = table;
1120 bvsmod_hobj.left = x;
1121 bvsmod_hobj.right = y;
1122 bvsmod_hobj.nbits = n;
1123 return int_htbl_get_obj(&table->htbl, &bvsmod_hobj.m);
1124 }
1125
get_bvshl(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1126 thvar_t get_bvshl(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1127 bvop_hobj_t bvshl_hobj;
1128
1129 bvshl_hobj.m.hash = (hobj_hash_t) hash_bvshl_hobj;
1130 bvshl_hobj.m.eq = (hobj_eq_t) eq_bvshl_hobj;
1131 bvshl_hobj.m.build = (hobj_build_t) build_bvshl_hobj;
1132 bvshl_hobj.tbl = table;
1133 bvshl_hobj.left = x;
1134 bvshl_hobj.right = y;
1135 bvshl_hobj.nbits = n;
1136 return int_htbl_get_obj(&table->htbl, &bvshl_hobj.m);
1137 }
1138
get_bvlshr(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1139 thvar_t get_bvlshr(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1140 bvop_hobj_t bvlshr_hobj;
1141
1142 bvlshr_hobj.m.hash = (hobj_hash_t) hash_bvlshr_hobj;
1143 bvlshr_hobj.m.eq = (hobj_eq_t) eq_bvlshr_hobj;
1144 bvlshr_hobj.m.build = (hobj_build_t) build_bvlshr_hobj;
1145 bvlshr_hobj.tbl = table;
1146 bvlshr_hobj.left = x;
1147 bvlshr_hobj.right = y;
1148 bvlshr_hobj.nbits = n;
1149 return int_htbl_get_obj(&table->htbl, &bvlshr_hobj.m);
1150 }
1151
get_bvashr(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y)1152 thvar_t get_bvashr(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y) {
1153 bvop_hobj_t bvashr_hobj;
1154
1155 bvashr_hobj.m.hash = (hobj_hash_t) hash_bvashr_hobj;
1156 bvashr_hobj.m.eq = (hobj_eq_t) eq_bvashr_hobj;
1157 bvashr_hobj.m.build = (hobj_build_t) build_bvashr_hobj;
1158 bvashr_hobj.tbl = table;
1159 bvashr_hobj.left = x;
1160 bvashr_hobj.right = y;
1161 bvashr_hobj.nbits = n;
1162 return int_htbl_get_obj(&table->htbl, &bvashr_hobj.m);
1163 }
1164
1165
get_bvadd(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y,bool * new_var)1166 thvar_t get_bvadd(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y, bool *new_var) {
1167 uint32_t nvars;
1168 thvar_t i;
1169 bvop_hobj_t bvadd_hobj;
1170
1171 bvadd_hobj.m.hash = (hobj_hash_t) hash_bvadd_hobj;
1172 bvadd_hobj.m.eq = (hobj_eq_t) eq_bvadd_hobj;
1173 bvadd_hobj.m.build = (hobj_build_t) build_bvadd_hobj;
1174 bvadd_hobj.tbl = table;
1175 bvadd_hobj.left = x;
1176 bvadd_hobj.right = y;
1177 bvadd_hobj.nbits = n;
1178
1179 nvars = table->nvars;
1180 i = int_htbl_get_obj(&table->htbl, &bvadd_hobj.m);
1181 *new_var = table->nvars > nvars;
1182
1183 return i;
1184 }
1185
get_bvsub(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y,bool * new_var)1186 thvar_t get_bvsub(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y, bool *new_var) {
1187 uint32_t nvars;
1188 thvar_t i;
1189 bvop_hobj_t bvsub_hobj;
1190
1191 bvsub_hobj.m.hash = (hobj_hash_t) hash_bvsub_hobj;
1192 bvsub_hobj.m.eq = (hobj_eq_t) eq_bvsub_hobj;
1193 bvsub_hobj.m.build = (hobj_build_t) build_bvsub_hobj;
1194 bvsub_hobj.tbl = table;
1195 bvsub_hobj.left = x;
1196 bvsub_hobj.right = y;
1197 bvsub_hobj.nbits = n;
1198
1199 nvars = table->nvars;
1200 i = int_htbl_get_obj(&table->htbl, &bvsub_hobj.m);
1201 *new_var = table->nvars > nvars;
1202
1203 return i;
1204 }
1205
get_bvmul(bv_vartable_t * table,uint32_t n,thvar_t x,thvar_t y,bool * new_var)1206 thvar_t get_bvmul(bv_vartable_t *table, uint32_t n, thvar_t x, thvar_t y, bool *new_var) {
1207 uint32_t nvars;
1208 thvar_t i;
1209 bvop_hobj_t bvmul_hobj;
1210
1211 bvmul_hobj.m.hash = (hobj_hash_t) hash_bvmul_hobj;
1212 bvmul_hobj.m.eq = (hobj_eq_t) eq_bvmul_hobj;
1213 bvmul_hobj.m.build = (hobj_build_t) build_bvmul_hobj;
1214 bvmul_hobj.tbl = table;
1215 bvmul_hobj.left = x;
1216 bvmul_hobj.right = y;
1217 bvmul_hobj.nbits = n;
1218
1219 nvars = table->nvars;
1220 i = int_htbl_get_obj(&table->htbl, &bvmul_hobj.m);
1221 *new_var = table->nvars > nvars;
1222
1223 return i;
1224 }
1225
get_bvneg(bv_vartable_t * table,uint32_t n,thvar_t x,bool * new_var)1226 thvar_t get_bvneg(bv_vartable_t *table, uint32_t n, thvar_t x, bool *new_var) {
1227 uint32_t nvars;
1228 thvar_t i;
1229 bvop_hobj_t bvneg_hobj;
1230
1231 bvneg_hobj.m.hash = (hobj_hash_t) hash_bvneg_hobj;
1232 bvneg_hobj.m.eq = (hobj_eq_t) eq_bvneg_hobj;
1233 bvneg_hobj.m.build = (hobj_build_t) build_bvneg_hobj;
1234 bvneg_hobj.tbl = table;
1235 bvneg_hobj.left = x;
1236 bvneg_hobj.right = null_thvar;
1237 bvneg_hobj.nbits = n;
1238
1239 nvars = table->nvars;
1240 i = int_htbl_get_obj(&table->htbl, &bvneg_hobj.m);
1241 *new_var = table->nvars > nvars;
1242
1243 return i;
1244 }
1245
1246
1247
1248
1249 /*
1250 * Search for (div x y), (rem x y), etc.
1251 * - return -1 if the term is not in the table
1252 */
find_div(bv_vartable_t * table,thvar_t x,thvar_t y)1253 thvar_t find_div(bv_vartable_t *table, thvar_t x, thvar_t y) {
1254 uint32_t n;
1255 bvop_hobj_t bvdiv_hobj;
1256
1257 assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1258 table->bit_size[x] == table->bit_size[y]);
1259
1260 n = table->bit_size[x];
1261
1262
1263 bvdiv_hobj.m.hash = (hobj_hash_t) hash_bvdiv_hobj;
1264 bvdiv_hobj.m.eq = (hobj_eq_t) eq_bvdiv_hobj;
1265 bvdiv_hobj.m.build = (hobj_build_t) build_bvdiv_hobj;
1266 bvdiv_hobj.tbl = table;
1267 bvdiv_hobj.left = x;
1268 bvdiv_hobj.right = y;
1269 bvdiv_hobj.nbits = n;
1270
1271 return int_htbl_find_obj(&table->htbl, &bvdiv_hobj.m);
1272 }
1273
find_rem(bv_vartable_t * table,thvar_t x,thvar_t y)1274 thvar_t find_rem(bv_vartable_t *table, thvar_t x, thvar_t y) {
1275 uint32_t n;
1276 bvop_hobj_t bvrem_hobj;
1277
1278 assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1279 table->bit_size[x] == table->bit_size[y]);
1280
1281 n = table->bit_size[x];
1282
1283 bvrem_hobj.m.hash = (hobj_hash_t) hash_bvrem_hobj;
1284 bvrem_hobj.m.eq = (hobj_eq_t) eq_bvrem_hobj;
1285 bvrem_hobj.m.build = (hobj_build_t) build_bvrem_hobj;
1286 bvrem_hobj.tbl = table;
1287 bvrem_hobj.left = x;
1288 bvrem_hobj.right = y;
1289 bvrem_hobj.nbits = n;
1290
1291 return int_htbl_find_obj(&table->htbl, &bvrem_hobj.m);
1292 }
1293
find_sdiv(bv_vartable_t * table,thvar_t x,thvar_t y)1294 thvar_t find_sdiv(bv_vartable_t *table, thvar_t x, thvar_t y) {
1295 uint32_t n;
1296 bvop_hobj_t bvsdiv_hobj;
1297
1298 assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1299 table->bit_size[x] == table->bit_size[y]);
1300
1301 n = table->bit_size[x];
1302
1303 bvsdiv_hobj.m.hash = (hobj_hash_t) hash_bvsdiv_hobj;
1304 bvsdiv_hobj.m.eq = (hobj_eq_t) eq_bvsdiv_hobj;
1305 bvsdiv_hobj.m.build = (hobj_build_t) build_bvsdiv_hobj;
1306 bvsdiv_hobj.tbl = table;
1307 bvsdiv_hobj.left = x;
1308 bvsdiv_hobj.right = y;
1309 bvsdiv_hobj.nbits = n;
1310
1311 return int_htbl_find_obj(&table->htbl, &bvsdiv_hobj.m);
1312 }
1313
find_srem(bv_vartable_t * table,thvar_t x,thvar_t y)1314 thvar_t find_srem(bv_vartable_t *table, thvar_t x, thvar_t y) {
1315 uint32_t n;
1316 bvop_hobj_t bvsrem_hobj;
1317
1318 assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1319 table->bit_size[x] == table->bit_size[y]);
1320
1321 n = table->bit_size[x];
1322
1323 bvsrem_hobj.m.hash = (hobj_hash_t) hash_bvsrem_hobj;
1324 bvsrem_hobj.m.eq = (hobj_eq_t) eq_bvsrem_hobj;
1325 bvsrem_hobj.m.build = (hobj_build_t) build_bvsrem_hobj;
1326 bvsrem_hobj.tbl = table;
1327 bvsrem_hobj.left = x;
1328 bvsrem_hobj.right = y;
1329 bvsrem_hobj.nbits = n;
1330
1331 return int_htbl_find_obj(&table->htbl, &bvsrem_hobj.m);
1332 }
1333
1334
find_bvadd(bv_vartable_t * table,thvar_t x,thvar_t y)1335 thvar_t find_bvadd(bv_vartable_t *table, thvar_t x, thvar_t y) {
1336 uint32_t n;
1337 bvop_hobj_t bvadd_hobj;
1338
1339 assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1340 table->bit_size[x] == table->bit_size[y]);
1341
1342 n = table->bit_size[x];
1343
1344 bvadd_hobj.m.hash = (hobj_hash_t) hash_bvadd_hobj;
1345 bvadd_hobj.m.eq = (hobj_eq_t) eq_bvadd_hobj;
1346 bvadd_hobj.m.build = (hobj_build_t) build_bvadd_hobj;
1347 bvadd_hobj.tbl = table;
1348 bvadd_hobj.left = x;
1349 bvadd_hobj.right = y;
1350 bvadd_hobj.nbits = n;
1351 return int_htbl_find_obj(&table->htbl, &bvadd_hobj.m);
1352 }
1353
find_bvsub(bv_vartable_t * table,thvar_t x,thvar_t y)1354 thvar_t find_bvsub(bv_vartable_t *table, thvar_t x, thvar_t y) {
1355 uint32_t n;
1356 bvop_hobj_t bvsub_hobj;
1357
1358 assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1359 table->bit_size[x] == table->bit_size[y]);
1360
1361 n = table->bit_size[x];
1362
1363 bvsub_hobj.m.hash = (hobj_hash_t) hash_bvsub_hobj;
1364 bvsub_hobj.m.eq = (hobj_eq_t) eq_bvsub_hobj;
1365 bvsub_hobj.m.build = (hobj_build_t) build_bvsub_hobj;
1366 bvsub_hobj.tbl = table;
1367 bvsub_hobj.left = x;
1368 bvsub_hobj.right = y;
1369 bvsub_hobj.nbits = n;
1370 return int_htbl_find_obj(&table->htbl, &bvsub_hobj.m);
1371 }
1372
find_bvmul(bv_vartable_t * table,thvar_t x,thvar_t y)1373 thvar_t find_bvmul(bv_vartable_t *table, thvar_t x, thvar_t y) {
1374 uint32_t n;
1375 bvop_hobj_t bvmul_hobj;
1376
1377 assert(valid_bvvar(table, x) && valid_bvvar(table, y) &&
1378 table->bit_size[x] == table->bit_size[y]);
1379
1380 n = table->bit_size[x];
1381
1382 bvmul_hobj.m.hash = (hobj_hash_t) hash_bvmul_hobj;
1383 bvmul_hobj.m.eq = (hobj_eq_t) eq_bvmul_hobj;
1384 bvmul_hobj.m.build = (hobj_build_t) build_bvmul_hobj;
1385 bvmul_hobj.tbl = table;
1386 bvmul_hobj.left = x;
1387 bvmul_hobj.right = y;
1388 bvmul_hobj.nbits = n;
1389 return int_htbl_find_obj(&table->htbl, &bvmul_hobj.m);
1390 }
1391
find_bvneg(bv_vartable_t * table,thvar_t x)1392 thvar_t find_bvneg(bv_vartable_t *table, thvar_t x) {
1393 uint32_t n;
1394 bvop_hobj_t bvneg_hobj;
1395
1396 assert(valid_bvvar(table, x));
1397
1398 n = table->bit_size[x];
1399
1400 bvneg_hobj.m.hash = (hobj_hash_t) hash_bvneg_hobj;
1401 bvneg_hobj.m.eq = (hobj_eq_t) eq_bvneg_hobj;
1402 bvneg_hobj.m.build = (hobj_build_t) build_bvneg_hobj;
1403 bvneg_hobj.tbl = table;
1404 bvneg_hobj.left = x;
1405 bvneg_hobj.right = null_thvar;
1406 bvneg_hobj.nbits = n;
1407 return int_htbl_find_obj(&table->htbl, &bvneg_hobj.m);
1408 }
1409