]> git.saurik.com Git - bison.git/blame - lib/vbitset.c
maint: run "make update-copyright".
[bison.git] / lib / vbitset.c
CommitLineData
cea53247 1/* Variable array bitsets.
6e30ede8 2
c932d613 3 Copyright (C) 2002-2006, 2009-2012 Free Software Foundation, Inc.
6e30ede8 4
cea53247
PE
5 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
6
f16b0819 7 This program is free software: you can redistribute it and/or modify
cea53247 8 it under the terms of the GNU General Public License as published by
f16b0819 9 the Free Software Foundation, either version 3 of the License, or
cea53247
PE
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
f16b0819 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
cea53247 19
231ed89a 20#include <config.h>
cea53247
PE
21
22#include "vbitset.h"
231ed89a 23
cea53247
PE
24#include <stdlib.h>
25#include <string.h>
26
27/* This file implements variable size bitsets stored as a variable
28 length array of words. Any unused bits in the last word must be
4d1801f1 29 zero.
cea53247
PE
30
31 Note that binary or ternary operations assume that each bitset operand
32 has the same size.
33*/
34
7d7d6663
PE
35static void vbitset_unused_clear (bitset);
36
37static void vbitset_set (bitset, bitset_bindex);
38static void vbitset_reset (bitset, bitset_bindex);
39static bool vbitset_test (bitset, bitset_bindex);
4d1801f1 40static bitset_bindex vbitset_list (bitset, bitset_bindex *,
7d7d6663
PE
41 bitset_bindex, bitset_bindex *);
42static bitset_bindex vbitset_list_reverse (bitset, bitset_bindex *,
43 bitset_bindex, bitset_bindex *);
cea53247
PE
44
45#define VBITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
46#define VBITSET_WORDS(X) ((X)->b.cdata)
47#define VBITSET_SIZE(X) ((X)->b.csize)
48#define VBITSET_ASIZE(X) ((X)->v.size)
49
4d1801f1
PE
50#undef min
51#undef max
cea53247
PE
52#define min(a, b) ((a) > (b) ? (b) : (a))
53#define max(a, b) ((a) > (b) ? (a) : (b))
54
55static bitset_bindex
88ab880d 56vbitset_resize (bitset src, bitset_bindex n_bits)
cea53247
PE
57{
58 bitset_windex oldsize;
59 bitset_windex newsize;
60
61 if (n_bits == BITSET_NBITS_ (src))
62 return n_bits;
63
64 oldsize = VBITSET_SIZE (src);
65 newsize = VBITSET_N_WORDS (n_bits);
66
67 if (oldsize < newsize)
68 {
69 bitset_windex size;
70
4d1801f1 71 /* The bitset needs to grow. If we already have enough memory
cea53247
PE
72 allocated, then just zero what we need. */
73 if (newsize > VBITSET_ASIZE (src))
74 {
75 /* We need to allocate more memory. When oldsize is
76 non-zero this means that we are changing the size, so
77 grow the bitset 25% larger than requested to reduce
78 number of reallocations. */
79
80 if (oldsize == 0)
81 size = newsize;
82 else
83 size = newsize + newsize / 4;
4d1801f1 84
cea53247
PE
85 VBITSET_WORDS (src)
86 = realloc (VBITSET_WORDS (src), size * sizeof (bitset_word));
87 VBITSET_ASIZE (src) = size;
88 }
89
4d1801f1 90 memset (VBITSET_WORDS (src) + oldsize, 0,
cea53247
PE
91 (newsize - oldsize) * sizeof (bitset_word));
92 VBITSET_SIZE (src) = newsize;
93 }
94 else
95 {
96 /* The bitset needs to shrink. There's no point deallocating
97 the memory unless it is shrinking by a reasonable amount. */
98 if ((oldsize - newsize) >= oldsize / 2)
99 {
100 VBITSET_WORDS (src)
101 = realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
102 VBITSET_ASIZE (src) = newsize;
103 }
104
105 /* Need to prune any excess bits. FIXME. */
106
107 VBITSET_SIZE (src) = newsize;
108 }
109
110 BITSET_NBITS_ (src) = n_bits;
111 return n_bits;
112}
113
114
115/* Set bit BITNO in bitset DST. */
116static void
117vbitset_set (dst, bitno)
118 bitset dst;
119 bitset_bindex bitno;
120{
121 bitset_windex windex = bitno / BITSET_WORD_BITS;
122
123 /* Perhaps we should abort. The user should explicitly call
124 bitset_resize since this will not catch the case when we set a
125 bit larger than the current size but smaller than the allocated
126 size. */
127 vbitset_resize (dst, bitno);
128
129 dst->b.cdata[windex - dst->b.cindex] |=
130 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
131}
132
133
134/* Reset bit BITNO in bitset DST. */
135static void
136vbitset_reset (dst, bitno)
137 bitset dst ATTRIBUTE_UNUSED;
138 bitset_bindex bitno ATTRIBUTE_UNUSED;
139{
140 /* We must be accessing outside the cache so the bit is
141 zero anyway. */
142}
143
144
145/* Test bit BITNO in bitset SRC. */
146static bool
147vbitset_test (src, bitno)
148 bitset src ATTRIBUTE_UNUSED;
149 bitset_bindex bitno ATTRIBUTE_UNUSED;
150{
151 /* We must be accessing outside the cache so the bit is
152 zero anyway. */
153 return 0;
154}
155
156
157/* Find list of up to NUM bits set in BSET in reverse order, starting
158 from and including NEXT and store in array LIST. Return with
159 actual number of bits found and with *NEXT indicating where search
160 stopped. */
161static bitset_bindex
162vbitset_list_reverse (src, list, num, next)
163 bitset src;
164 bitset_bindex *list;
165 bitset_bindex num;
166 bitset_bindex *next;
167{
168 bitset_bindex bitno;
169 bitset_bindex rbitno;
170 bitset_bindex count;
171 bitset_windex windex;
172 unsigned int bitcnt;
173 bitset_bindex bitoff;
174 bitset_word *srcp = VBITSET_WORDS (src);
175 bitset_bindex n_bits = BITSET_SIZE_ (src);
176
177 rbitno = *next;
178
179 /* If num is 1, we could speed things up with a binary search
180 of the word of interest. */
181
182 if (rbitno >= n_bits)
183 return 0;
184
185 count = 0;
186
187 bitno = n_bits - (rbitno + 1);
188
189 windex = bitno / BITSET_WORD_BITS;
190 bitcnt = bitno % BITSET_WORD_BITS;
191 bitoff = windex * BITSET_WORD_BITS;
192
193 do
194 {
195 bitset_word word;
196
197 word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
198 for (; word; bitcnt--)
199 {
200 if (word & BITSET_MSB)
201 {
202 list[count++] = bitoff + bitcnt;
203 if (count >= num)
204 {
205 *next = n_bits - (bitoff + bitcnt);
206 return count;
207 }
208 }
209 word <<= 1;
210 }
211 bitoff -= BITSET_WORD_BITS;
212 bitcnt = BITSET_WORD_BITS - 1;
213 }
214 while (windex--);
215
216 *next = n_bits - (bitoff + 1);
217 return count;
218}
219
220
221/* Find list of up to NUM bits set in BSET starting from and including
222 *NEXT and store in array LIST. Return with actual number of bits
223 found and with *NEXT indicating where search stopped. */
224static bitset_bindex
225vbitset_list (src, list, num, next)
226 bitset src;
227 bitset_bindex *list;
228 bitset_bindex num;
229 bitset_bindex *next;
230{
231 bitset_bindex bitno;
232 bitset_bindex count;
233 bitset_windex windex;
234 bitset_bindex bitoff;
235 bitset_windex size = VBITSET_SIZE (src);
236 bitset_word *srcp = VBITSET_WORDS (src);
237 bitset_word word;
238
239 bitno = *next;
240
241 count = 0;
242 if (!bitno)
243 {
244 /* Many bitsets are zero, so make this common case fast. */
245 for (windex = 0; windex < size && !srcp[windex]; windex++)
246 continue;
247 if (windex >= size)
248 return 0;
249
250 /* If num is 1, we could speed things up with a binary search
251 of the current word. */
252
253 bitoff = windex * BITSET_WORD_BITS;
254 }
255 else
256 {
257 if (bitno >= BITSET_SIZE_ (src))
258 return 0;
259
260 windex = bitno / BITSET_WORD_BITS;
261 bitno = bitno % BITSET_WORD_BITS;
262
263 if (bitno)
264 {
265 /* Handle the case where we start within a word.
266 Most often, this is executed with large bitsets
267 with many set bits where we filled the array
268 on the previous call to this function. */
269
270 bitoff = windex * BITSET_WORD_BITS;
271 word = srcp[windex] >> bitno;
272 for (bitno = bitoff + bitno; word; bitno++)
273 {
274 if (word & 1)
275 {
276 list[count++] = bitno;
277 if (count >= num)
278 {
279 *next = bitno + 1;
280 return count;
281 }
282 }
283 word >>= 1;
284 }
285 windex++;
286 }
287 bitoff = windex * BITSET_WORD_BITS;
288 }
289
290 for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
291 {
292 if (!(word = srcp[windex]))
293 continue;
294
295 if ((count + BITSET_WORD_BITS) < num)
296 {
297 for (bitno = bitoff; word; bitno++)
298 {
299 if (word & 1)
300 list[count++] = bitno;
301 word >>= 1;
302 }
303 }
304 else
305 {
306 for (bitno = bitoff; word; bitno++)
307 {
308 if (word & 1)
309 {
310 list[count++] = bitno;
311 if (count >= num)
312 {
313 *next = bitno + 1;
314 return count;
315 }
316 }
317 word >>= 1;
318 }
319 }
320 }
321
322 *next = bitoff;
323 return count;
324}
325
326
327/* Ensure that any unused bits within the last word are clear. */
328static inline void
329vbitset_unused_clear (dst)
330 bitset dst;
331{
332 unsigned int last_bit;
333
334 last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
335 if (last_bit)
336 VBITSET_WORDS (dst)[VBITSET_SIZE (dst) - 1] &=
337 ((bitset_word) 1 << last_bit) - 1;
338}
339
340
341static void
88ab880d 342vbitset_ones (bitset dst)
cea53247
PE
343{
344 bitset_word *dstp = VBITSET_WORDS (dst);
345 unsigned int bytes;
346
347 bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
348
349 memset (dstp, -1, bytes);
350 vbitset_unused_clear (dst);
351}
352
353
354static void
88ab880d 355vbitset_zero (bitset dst)
cea53247
PE
356{
357 bitset_word *dstp = VBITSET_WORDS (dst);
358 unsigned int bytes;
359
360 bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
361
362 memset (dstp, 0, bytes);
363}
364
365
366static bool
88ab880d 367vbitset_empty_p (bitset dst)
cea53247
PE
368{
369 unsigned int i;
370 bitset_word *dstp = VBITSET_WORDS (dst);
371
372 for (i = 0; i < VBITSET_SIZE (dst); i++)
373 if (dstp[i])
374 return 0;
375
376 return 1;
377}
378
379
380static void
88ab880d 381vbitset_copy1 (bitset dst, bitset src)
cea53247
PE
382{
383 bitset_word *srcp;
384 bitset_word *dstp;
385 bitset_windex ssize;
386 bitset_windex dsize;
387
388 if (src == dst)
389 return;
390
391 vbitset_resize (dst, BITSET_SIZE_ (src));
392
393 srcp = VBITSET_WORDS (src);
394 dstp = VBITSET_WORDS (dst);
395 ssize = VBITSET_SIZE (src);
396 dsize = VBITSET_SIZE (dst);
397
398 memcpy (dstp, srcp, sizeof (bitset_word) * ssize);
399
400 memset (dstp + sizeof (bitset_word) * ssize, 0,
401 sizeof (bitset_word) * (dsize - ssize));
402}
403
404
405static void
88ab880d 406vbitset_not (bitset dst, bitset src)
cea53247
PE
407{
408 unsigned int i;
409 bitset_word *srcp;
410 bitset_word *dstp;
411 bitset_windex ssize;
412 bitset_windex dsize;
413
414 vbitset_resize (dst, BITSET_SIZE_ (src));
415
416 srcp = VBITSET_WORDS (src);
417 dstp = VBITSET_WORDS (dst);
418 ssize = VBITSET_SIZE (src);
419 dsize = VBITSET_SIZE (dst);
420
421 for (i = 0; i < ssize; i++)
422 *dstp++ = ~(*srcp++);
423
424 vbitset_unused_clear (dst);
425 memset (dstp + sizeof (bitset_word) * ssize, 0,
426 sizeof (bitset_word) * (dsize - ssize));
427}
428
4d1801f1 429
cea53247 430static bool
88ab880d 431vbitset_equal_p (bitset dst, bitset src)
cea53247
PE
432{
433 unsigned int i;
434 bitset_word *srcp = VBITSET_WORDS (src);
435 bitset_word *dstp = VBITSET_WORDS (dst);
436 bitset_windex ssize = VBITSET_SIZE (src);
437 bitset_windex dsize = VBITSET_SIZE (dst);
438
439 for (i = 0; i < min (ssize, dsize); i++)
440 if (*srcp++ != *dstp++)
441 return 0;
442
443 if (ssize > dsize)
444 {
445 for (; i < ssize; i++)
446 if (*srcp++)
447 return 0;
448 }
449 else
450 {
451 for (; i < dsize; i++)
452 if (*dstp++)
453 return 0;
454 }
455
456 return 1;
457}
458
459
460static bool
88ab880d 461vbitset_subset_p (bitset dst, bitset src)
cea53247
PE
462{
463 unsigned int i;
464 bitset_word *srcp = VBITSET_WORDS (src);
465 bitset_word *dstp = VBITSET_WORDS (dst);
466 bitset_windex ssize = VBITSET_SIZE (src);
467 bitset_windex dsize = VBITSET_SIZE (dst);
4d1801f1 468
cea53247
PE
469 for (i = 0; i < min (ssize, dsize); i++, dstp++, srcp++)
470 if (*dstp != (*srcp | *dstp))
471 return 0;
472
473 if (ssize > dsize)
474 {
475 for (; i < ssize; i++)
476 if (*srcp++)
477 return 0;
478 }
479
480 return 1;
481}
482
483
484static bool
88ab880d 485vbitset_disjoint_p (bitset dst, bitset src)
cea53247
PE
486{
487 unsigned int i;
488 bitset_word *srcp = VBITSET_WORDS (src);
489 bitset_word *dstp = VBITSET_WORDS (dst);
490 bitset_windex ssize = VBITSET_SIZE (src);
491 bitset_windex dsize = VBITSET_SIZE (dst);
492
493 for (i = 0; i < min (ssize, dsize); i++)
494 if (*srcp++ & *dstp++)
495 return 0;
496
497 return 1;
498}
499
500
501static void
88ab880d 502vbitset_and (bitset dst, bitset src1, bitset src2)
cea53247
PE
503{
504 unsigned int i;
505 bitset_word *src1p;
506 bitset_word *src2p;
507 bitset_word *dstp;
508 bitset_windex ssize1;
509 bitset_windex ssize2;
510 bitset_windex dsize;
511
512 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
513
514 dsize = VBITSET_SIZE (dst);
515 ssize1 = VBITSET_SIZE (src1);
516 ssize2 = VBITSET_SIZE (src2);
517 dstp = VBITSET_WORDS (dst);
518 src1p = VBITSET_WORDS (src1);
519 src2p = VBITSET_WORDS (src2);
520
521 for (i = 0; i < min (ssize1, ssize2); i++)
522 *dstp++ = *src1p++ & *src2p++;
4d1801f1 523
cea53247
PE
524 memset (dstp, 0, sizeof (bitset_word) * (dsize - min (ssize1, ssize2)));
525}
526
527
528static bool
88ab880d 529vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
cea53247
PE
530{
531 unsigned int i;
532 int changed = 0;
533 bitset_word *src1p;
534 bitset_word *src2p;
535 bitset_word *dstp;
536 bitset_windex ssize1;
537 bitset_windex ssize2;
538 bitset_windex dsize;
539
540 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
541
542 dsize = VBITSET_SIZE (dst);
543 ssize1 = VBITSET_SIZE (src1);
544 ssize2 = VBITSET_SIZE (src2);
545 dstp = VBITSET_WORDS (dst);
546 src1p = VBITSET_WORDS (src1);
547 src2p = VBITSET_WORDS (src2);
548
549 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
550 {
551 bitset_word tmp = *src1p++ & *src2p++;
4d1801f1 552
cea53247
PE
553 if (*dstp != tmp)
554 {
555 changed = 1;
556 *dstp = tmp;
557 }
558 }
4d1801f1 559
cea53247
PE
560 if (ssize2 > ssize1)
561 {
562 src1p = src2p;
563 ssize1 = ssize2;
564 }
565
566 for (; i < ssize1; i++, dstp++)
567 {
568 if (*dstp != 0)
569 {
570 changed = 1;
571 *dstp = 0;
572 }
573 }
574
575 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
576
577 return changed;
578}
579
580
581static void
88ab880d 582vbitset_andn (bitset dst, bitset src1, bitset src2)
cea53247
PE
583{
584 unsigned int i;
585 bitset_word *src1p;
586 bitset_word *src2p;
587 bitset_word *dstp;
588 bitset_windex ssize1;
589 bitset_windex ssize2;
590 bitset_windex dsize;
591
592 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
593
594 dsize = VBITSET_SIZE (dst);
595 ssize1 = VBITSET_SIZE (src1);
596 ssize2 = VBITSET_SIZE (src2);
597 dstp = VBITSET_WORDS (dst);
598 src1p = VBITSET_WORDS (src1);
599 src2p = VBITSET_WORDS (src2);
600
601 for (i = 0; i < min (ssize1, ssize2); i++)
602 *dstp++ = *src1p++ & ~(*src2p++);
4d1801f1 603
cea53247
PE
604 if (ssize2 > ssize1)
605 {
606 for (; i < ssize2; i++)
607 *dstp++ = 0;
608
609 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
610 }
611 else
612 {
613 for (; i < ssize1; i++)
614 *dstp++ = *src1p++;
615
616 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
617 }
618}
619
620
621static bool
88ab880d 622vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
cea53247
PE
623{
624 unsigned int i;
625 int changed = 0;
626 bitset_word *src1p;
627 bitset_word *src2p;
628 bitset_word *dstp;
629 bitset_windex ssize1;
630 bitset_windex ssize2;
631 bitset_windex dsize;
632
633 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
634
635 dsize = VBITSET_SIZE (dst);
636 ssize1 = VBITSET_SIZE (src1);
637 ssize2 = VBITSET_SIZE (src2);
638 dstp = VBITSET_WORDS (dst);
639 src1p = VBITSET_WORDS (src1);
640 src2p = VBITSET_WORDS (src2);
641
642 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
643 {
644 bitset_word tmp = *src1p++ & ~(*src2p++);
4d1801f1 645
cea53247
PE
646 if (*dstp != tmp)
647 {
648 changed = 1;
649 *dstp = tmp;
650 }
651 }
4d1801f1 652
cea53247
PE
653 if (ssize2 > ssize1)
654 {
655 for (; i < ssize2; i++, dstp++)
656 {
657 if (*dstp != 0)
658 {
659 changed = 1;
660 *dstp = 0;
661 }
662 }
663
664 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
665 }
666 else
667 {
668 for (; i < ssize1; i++, dstp++)
669 {
670 bitset_word tmp = *src1p++;
4d1801f1 671
cea53247
PE
672 if (*dstp != tmp)
673 {
674 changed = 1;
675 *dstp = tmp;
676 }
677 }
678
679 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
680 }
681
682 return changed;
683}
684
685
686static void
88ab880d 687vbitset_or (bitset dst, bitset src1, bitset src2)
cea53247
PE
688{
689 unsigned int i;
690 bitset_word *src1p;
691 bitset_word *src2p;
692 bitset_word *dstp;
693 bitset_windex ssize1;
694 bitset_windex ssize2;
695 bitset_windex dsize;
696
697 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
698
699 dsize = VBITSET_SIZE (dst);
700 ssize1 = VBITSET_SIZE (src1);
701 ssize2 = VBITSET_SIZE (src2);
702 dstp = VBITSET_WORDS (dst);
703 src1p = VBITSET_WORDS (src1);
704 src2p = VBITSET_WORDS (src2);
705
706 for (i = 0; i < min (ssize1, ssize2); i++)
707 *dstp++ = *src1p++ | *src2p++;
4d1801f1 708
cea53247
PE
709 if (ssize2 > ssize1)
710 {
711 src1p = src2p;
712 ssize1 = ssize2;
713 }
714
715 for (; i < ssize1; i++)
716 *dstp++ = *src1p++;
717
718 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
719}
720
721
722static bool
88ab880d 723vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
cea53247
PE
724{
725 unsigned int i;
726 int changed = 0;
727 bitset_word *src1p;
728 bitset_word *src2p;
729 bitset_word *dstp;
730 bitset_windex ssize1;
731 bitset_windex ssize2;
732 bitset_windex dsize;
733
734 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
735
736 dsize = VBITSET_SIZE (dst);
737 ssize1 = VBITSET_SIZE (src1);
738 ssize2 = VBITSET_SIZE (src2);
739 dstp = VBITSET_WORDS (dst);
740 src1p = VBITSET_WORDS (src1);
741 src2p = VBITSET_WORDS (src2);
742
743 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
744 {
745 bitset_word tmp = *src1p++ | *src2p++;
4d1801f1 746
cea53247
PE
747 if (*dstp != tmp)
748 {
749 changed = 1;
750 *dstp = tmp;
751 }
752 }
4d1801f1 753
cea53247
PE
754 if (ssize2 > ssize1)
755 {
756 src1p = src2p;
757 ssize1 = ssize2;
758 }
759
760 for (; i < ssize1; i++, dstp++)
761 {
762 bitset_word tmp = *src1p++;
4d1801f1 763
cea53247
PE
764 if (*dstp != tmp)
765 {
766 changed = 1;
767 *dstp = tmp;
768 }
769 }
770
771 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
772
773 return changed;
774}
775
776
777static void
88ab880d 778vbitset_xor (bitset dst, bitset src1, bitset src2)
cea53247
PE
779{
780 unsigned int i;
781 bitset_word *src1p;
782 bitset_word *src2p;
783 bitset_word *dstp;
784 bitset_windex ssize1;
785 bitset_windex ssize2;
786 bitset_windex dsize;
787
788 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
789
790 dsize = VBITSET_SIZE (dst);
791 ssize1 = VBITSET_SIZE (src1);
792 ssize2 = VBITSET_SIZE (src2);
793 dstp = VBITSET_WORDS (dst);
794 src1p = VBITSET_WORDS (src1);
795 src2p = VBITSET_WORDS (src2);
796
797 for (i = 0; i < min (ssize1, ssize2); i++)
798 *dstp++ = *src1p++ ^ *src2p++;
4d1801f1 799
cea53247
PE
800 if (ssize2 > ssize1)
801 {
802 src1p = src2p;
803 ssize1 = ssize2;
804 }
805
806 for (; i < ssize1; i++)
807 *dstp++ = *src1p++;
808
809 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
810}
811
812
813static bool
88ab880d 814vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
cea53247
PE
815{
816 unsigned int i;
817 int changed = 0;
818 bitset_word *src1p;
819 bitset_word *src2p;
820 bitset_word *dstp;
821 bitset_windex ssize1;
822 bitset_windex ssize2;
823 bitset_windex dsize;
824
825 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
826
827 dsize = VBITSET_SIZE (dst);
828 ssize1 = VBITSET_SIZE (src1);
829 ssize2 = VBITSET_SIZE (src2);
830 dstp = VBITSET_WORDS (dst);
831 src1p = VBITSET_WORDS (src1);
832 src2p = VBITSET_WORDS (src2);
833
834 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
835 {
836 bitset_word tmp = *src1p++ ^ *src2p++;
4d1801f1 837
cea53247
PE
838 if (*dstp != tmp)
839 {
840 changed = 1;
841 *dstp = tmp;
842 }
843 }
4d1801f1 844
cea53247
PE
845 if (ssize2 > ssize1)
846 {
847 src1p = src2p;
848 ssize1 = ssize2;
849 }
850
851 for (; i < ssize1; i++, dstp++)
852 {
853 bitset_word tmp = *src1p++;
4d1801f1 854
cea53247
PE
855 if (*dstp != tmp)
856 {
857 changed = 1;
858 *dstp = tmp;
859 }
860 }
861
862 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
863
864 return changed;
865}
866
867
868/* FIXME, these operations need fixing for different size
869 bitsets. */
870
871static void
88ab880d 872vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
873{
874 unsigned int i;
875 bitset_word *src1p;
876 bitset_word *src2p;
877 bitset_word *src3p;
878 bitset_word *dstp;
879 bitset_windex size;
4d1801f1 880
cea53247
PE
881 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
882 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
883 {
884 bitset_and_or_ (dst, src1, src2, src3);
885 return;
886 }
887
888 vbitset_resize (dst, BITSET_NBITS_ (src1));
889
890 src1p = VBITSET_WORDS (src1);
891 src2p = VBITSET_WORDS (src2);
892 src3p = VBITSET_WORDS (src3);
893 dstp = VBITSET_WORDS (dst);
894 size = VBITSET_SIZE (dst);
895
896 for (i = 0; i < size; i++)
897 *dstp++ = (*src1p++ & *src2p++) | *src3p++;
898}
899
900
901static bool
88ab880d 902vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
903{
904 unsigned int i;
905 int changed = 0;
906 bitset_word *src1p;
907 bitset_word *src2p;
908 bitset_word *src3p;
909 bitset_word *dstp;
910 bitset_windex size;
4d1801f1 911
cea53247
PE
912 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
913 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
914 return bitset_and_or_cmp_ (dst, src1, src2, src3);
915
916 vbitset_resize (dst, BITSET_NBITS_ (src1));
917
918 src1p = VBITSET_WORDS (src1);
919 src2p = VBITSET_WORDS (src2);
920 src3p = VBITSET_WORDS (src3);
921 dstp = VBITSET_WORDS (dst);
922 size = VBITSET_SIZE (dst);
4d1801f1 923
cea53247
PE
924 for (i = 0; i < size; i++, dstp++)
925 {
926 bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
4d1801f1 927
cea53247
PE
928 if (*dstp != tmp)
929 {
930 changed = 1;
931 *dstp = tmp;
932 }
933 }
934 return changed;
935}
936
937
938static void
88ab880d 939vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
940{
941 unsigned int i;
942 bitset_word *src1p;
943 bitset_word *src2p;
944 bitset_word *src3p;
945 bitset_word *dstp;
946 bitset_windex size;
4d1801f1 947
cea53247
PE
948 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
949 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
950 {
951 bitset_andn_or_ (dst, src1, src2, src3);
952 return;
953 }
954
955 vbitset_resize (dst, BITSET_NBITS_ (src1));
956
957 src1p = VBITSET_WORDS (src1);
958 src2p = VBITSET_WORDS (src2);
959 src3p = VBITSET_WORDS (src3);
960 dstp = VBITSET_WORDS (dst);
961 size = VBITSET_SIZE (dst);
962
963 for (i = 0; i < size; i++)
964 *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
965}
966
967
968static bool
88ab880d 969vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
970{
971 unsigned int i;
972 int changed = 0;
973 bitset_word *src1p;
974 bitset_word *src2p;
975 bitset_word *src3p;
976 bitset_word *dstp;
977 bitset_windex size;
4d1801f1 978
cea53247
PE
979 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
980 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
981 return bitset_andn_or_cmp_ (dst, src1, src2, src3);
982
983 vbitset_resize (dst, BITSET_NBITS_ (src1));
984
985 src1p = VBITSET_WORDS (src1);
986 src2p = VBITSET_WORDS (src2);
987 src3p = VBITSET_WORDS (src3);
988 dstp = VBITSET_WORDS (dst);
989 size = VBITSET_SIZE (dst);
4d1801f1 990
cea53247
PE
991 for (i = 0; i < size; i++, dstp++)
992 {
993 bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
4d1801f1 994
cea53247
PE
995 if (*dstp != tmp)
996 {
997 changed = 1;
998 *dstp = tmp;
999 }
1000 }
1001 return changed;
1002}
1003
1004
1005static void
88ab880d 1006vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
1007{
1008 unsigned int i;
1009 bitset_word *src1p;
1010 bitset_word *src2p;
1011 bitset_word *src3p;
1012 bitset_word *dstp;
1013 bitset_windex size;
4d1801f1 1014
cea53247
PE
1015 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
1016 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
1017 {
1018 bitset_or_and_ (dst, src1, src2, src3);
1019 return;
1020 }
1021
1022 vbitset_resize (dst, BITSET_NBITS_ (src1));
1023
1024 src1p = VBITSET_WORDS (src1);
1025 src2p = VBITSET_WORDS (src2);
1026 src3p = VBITSET_WORDS (src3);
1027 dstp = VBITSET_WORDS (dst);
1028 size = VBITSET_SIZE (dst);
4d1801f1 1029
cea53247
PE
1030 for (i = 0; i < size; i++)
1031 *dstp++ = (*src1p++ | *src2p++) & *src3p++;
1032}
1033
1034
1035static bool
88ab880d 1036vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
cea53247
PE
1037{
1038 unsigned int i;
1039 int changed = 0;
1040 bitset_word *src1p;
1041 bitset_word *src2p;
1042 bitset_word *src3p;
1043 bitset_word *dstp;
1044 bitset_windex size;
4d1801f1 1045
cea53247
PE
1046 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
1047 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
1048 return bitset_or_and_cmp_ (dst, src1, src2, src3);
1049
1050 vbitset_resize (dst, BITSET_NBITS_ (src1));
1051
1052 src1p = VBITSET_WORDS (src1);
1053 src2p = VBITSET_WORDS (src2);
1054 src3p = VBITSET_WORDS (src3);
1055 dstp = VBITSET_WORDS (dst);
1056 size = VBITSET_SIZE (dst);
4d1801f1 1057
cea53247
PE
1058 for (i = 0; i < size; i++, dstp++)
1059 {
1060 bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
4d1801f1 1061
cea53247
PE
1062 if (*dstp != tmp)
1063 {
1064 changed = 1;
1065 *dstp = tmp;
1066 }
1067 }
1068 return changed;
1069}
1070
1071
98bb5428 1072static void
88ab880d 1073vbitset_copy (bitset dst, bitset src)
cea53247
PE
1074{
1075 if (BITSET_COMPATIBLE_ (dst, src))
1076 vbitset_copy1 (dst, src);
1077 else
1078 bitset_copy_ (dst, src);
1079}
1080
1081
1082/* Vector of operations for multiple word bitsets. */
1083struct bitset_vtable vbitset_vtable = {
1084 vbitset_set,
1085 vbitset_reset,
1086 bitset_toggle_,
1087 vbitset_test,
1088 vbitset_resize,
1089 bitset_size_,
1090 bitset_count_,
1091 vbitset_empty_p,
1092 vbitset_ones,
1093 vbitset_zero,
1094 vbitset_copy,
1095 vbitset_disjoint_p,
1096 vbitset_equal_p,
1097 vbitset_not,
1098 vbitset_subset_p,
1099 vbitset_and,
1100 vbitset_and_cmp,
1101 vbitset_andn,
1102 vbitset_andn_cmp,
1103 vbitset_or,
1104 vbitset_or_cmp,
1105 vbitset_xor,
1106 vbitset_xor_cmp,
1107 vbitset_and_or,
1108 vbitset_and_or_cmp,
1109 vbitset_andn_or,
1110 vbitset_andn_or_cmp,
1111 vbitset_or_and,
1112 vbitset_or_and_cmp,
1113 vbitset_list,
1114 vbitset_list_reverse,
1115 NULL,
1116 BITSET_VARRAY
1117};
1118
1119
1120size_t
1121vbitset_bytes (n_bits)
1122 bitset_bindex n_bits ATTRIBUTE_UNUSED;
1123{
1124 return sizeof (struct vbitset_struct);
1125}
1126
1127
1128bitset
1129vbitset_init (bset, n_bits)
1130 bitset bset;
1131 bitset_bindex n_bits;
1132{
1133 bset->b.vtable = &vbitset_vtable;
1134
1135 bset->b.cindex = 0;
1136
1137 VBITSET_SIZE (bset) = 0;
1138 vbitset_resize (bset, n_bits);
1139 return bset;
1140}