Regen.
[bison/ericb.git] / lib / vbitset.c
blob802fdae4866bc0624f75a726527303b054c3e3e4
1 /* Variable array bitsets.
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
5 This program 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.
10 This program 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.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 #include <config.h>
20 #include "vbitset.h"
22 #include <stdlib.h>
23 #include <string.h>
25 /* This file implements variable size bitsets stored as a variable
26 length array of words. Any unused bits in the last word must be
27 zero.
29 Note that binary or ternary operations assume that each bitset operand
30 has the same size.
33 static void vbitset_unused_clear (bitset);
35 static void vbitset_set (bitset, bitset_bindex);
36 static void vbitset_reset (bitset, bitset_bindex);
37 static bool vbitset_test (bitset, bitset_bindex);
38 static bitset_bindex vbitset_list (bitset, bitset_bindex *,
39 bitset_bindex, bitset_bindex *);
40 static bitset_bindex vbitset_list_reverse (bitset, bitset_bindex *,
41 bitset_bindex, bitset_bindex *);
43 #define VBITSET_N_WORDS(N) (((N) + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
44 #define VBITSET_WORDS(X) ((X)->b.cdata)
45 #define VBITSET_SIZE(X) ((X)->b.csize)
46 #define VBITSET_ASIZE(X) ((X)->v.size)
48 #undef min
49 #undef max
50 #define min(a, b) ((a) > (b) ? (b) : (a))
51 #define max(a, b) ((a) > (b) ? (a) : (b))
53 static bitset_bindex
54 vbitset_resize (bitset src, bitset_bindex n_bits)
56 bitset_windex oldsize;
57 bitset_windex newsize;
59 if (n_bits == BITSET_NBITS_ (src))
60 return n_bits;
62 oldsize = VBITSET_SIZE (src);
63 newsize = VBITSET_N_WORDS (n_bits);
65 if (oldsize < newsize)
67 bitset_windex size;
69 /* The bitset needs to grow. If we already have enough memory
70 allocated, then just zero what we need. */
71 if (newsize > VBITSET_ASIZE (src))
73 /* We need to allocate more memory. When oldsize is
74 non-zero this means that we are changing the size, so
75 grow the bitset 25% larger than requested to reduce
76 number of reallocations. */
78 if (oldsize == 0)
79 size = newsize;
80 else
81 size = newsize + newsize / 4;
83 VBITSET_WORDS (src)
84 = realloc (VBITSET_WORDS (src), size * sizeof (bitset_word));
85 VBITSET_ASIZE (src) = size;
88 memset (VBITSET_WORDS (src) + oldsize, 0,
89 (newsize - oldsize) * sizeof (bitset_word));
90 VBITSET_SIZE (src) = newsize;
92 else
94 /* The bitset needs to shrink. There's no point deallocating
95 the memory unless it is shrinking by a reasonable amount. */
96 if ((oldsize - newsize) >= oldsize / 2)
98 VBITSET_WORDS (src)
99 = realloc (VBITSET_WORDS (src), newsize * sizeof (bitset_word));
100 VBITSET_ASIZE (src) = newsize;
103 /* Need to prune any excess bits. FIXME. */
105 VBITSET_SIZE (src) = newsize;
108 BITSET_NBITS_ (src) = n_bits;
109 return n_bits;
113 /* Set bit BITNO in bitset DST. */
114 static void
115 vbitset_set (dst, bitno)
116 bitset dst;
117 bitset_bindex bitno;
119 bitset_windex windex = bitno / BITSET_WORD_BITS;
121 /* Perhaps we should abort. The user should explicitly call
122 bitset_resize since this will not catch the case when we set a
123 bit larger than the current size but smaller than the allocated
124 size. */
125 vbitset_resize (dst, bitno);
127 dst->b.cdata[windex - dst->b.cindex] |=
128 (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
132 /* Reset bit BITNO in bitset DST. */
133 static void
134 vbitset_reset (dst, bitno)
135 bitset dst ATTRIBUTE_UNUSED;
136 bitset_bindex bitno ATTRIBUTE_UNUSED;
138 /* We must be accessing outside the cache so the bit is
139 zero anyway. */
143 /* Test bit BITNO in bitset SRC. */
144 static bool
145 vbitset_test (src, bitno)
146 bitset src ATTRIBUTE_UNUSED;
147 bitset_bindex bitno ATTRIBUTE_UNUSED;
149 /* We must be accessing outside the cache so the bit is
150 zero anyway. */
151 return 0;
155 /* Find list of up to NUM bits set in BSET in reverse order, starting
156 from and including NEXT and store in array LIST. Return with
157 actual number of bits found and with *NEXT indicating where search
158 stopped. */
159 static bitset_bindex
160 vbitset_list_reverse (src, list, num, next)
161 bitset src;
162 bitset_bindex *list;
163 bitset_bindex num;
164 bitset_bindex *next;
166 bitset_bindex bitno;
167 bitset_bindex rbitno;
168 bitset_bindex count;
169 bitset_windex windex;
170 unsigned int bitcnt;
171 bitset_bindex bitoff;
172 bitset_word *srcp = VBITSET_WORDS (src);
173 bitset_bindex n_bits = BITSET_SIZE_ (src);
175 rbitno = *next;
177 /* If num is 1, we could speed things up with a binary search
178 of the word of interest. */
180 if (rbitno >= n_bits)
181 return 0;
183 count = 0;
185 bitno = n_bits - (rbitno + 1);
187 windex = bitno / BITSET_WORD_BITS;
188 bitcnt = bitno % BITSET_WORD_BITS;
189 bitoff = windex * BITSET_WORD_BITS;
193 bitset_word word;
195 word = srcp[windex] << (BITSET_WORD_BITS - 1 - bitcnt);
196 for (; word; bitcnt--)
198 if (word & BITSET_MSB)
200 list[count++] = bitoff + bitcnt;
201 if (count >= num)
203 *next = n_bits - (bitoff + bitcnt);
204 return count;
207 word <<= 1;
209 bitoff -= BITSET_WORD_BITS;
210 bitcnt = BITSET_WORD_BITS - 1;
212 while (windex--);
214 *next = n_bits - (bitoff + 1);
215 return count;
219 /* Find list of up to NUM bits set in BSET starting from and including
220 *NEXT and store in array LIST. Return with actual number of bits
221 found and with *NEXT indicating where search stopped. */
222 static bitset_bindex
223 vbitset_list (src, list, num, next)
224 bitset src;
225 bitset_bindex *list;
226 bitset_bindex num;
227 bitset_bindex *next;
229 bitset_bindex bitno;
230 bitset_bindex count;
231 bitset_windex windex;
232 bitset_bindex bitoff;
233 bitset_windex size = VBITSET_SIZE (src);
234 bitset_word *srcp = VBITSET_WORDS (src);
235 bitset_word word;
237 bitno = *next;
239 count = 0;
240 if (!bitno)
242 /* Many bitsets are zero, so make this common case fast. */
243 for (windex = 0; windex < size && !srcp[windex]; windex++)
244 continue;
245 if (windex >= size)
246 return 0;
248 /* If num is 1, we could speed things up with a binary search
249 of the current word. */
251 bitoff = windex * BITSET_WORD_BITS;
253 else
255 if (bitno >= BITSET_SIZE_ (src))
256 return 0;
258 windex = bitno / BITSET_WORD_BITS;
259 bitno = bitno % BITSET_WORD_BITS;
261 if (bitno)
263 /* Handle the case where we start within a word.
264 Most often, this is executed with large bitsets
265 with many set bits where we filled the array
266 on the previous call to this function. */
268 bitoff = windex * BITSET_WORD_BITS;
269 word = srcp[windex] >> bitno;
270 for (bitno = bitoff + bitno; word; bitno++)
272 if (word & 1)
274 list[count++] = bitno;
275 if (count >= num)
277 *next = bitno + 1;
278 return count;
281 word >>= 1;
283 windex++;
285 bitoff = windex * BITSET_WORD_BITS;
288 for (; windex < size; windex++, bitoff += BITSET_WORD_BITS)
290 if (!(word = srcp[windex]))
291 continue;
293 if ((count + BITSET_WORD_BITS) < num)
295 for (bitno = bitoff; word; bitno++)
297 if (word & 1)
298 list[count++] = bitno;
299 word >>= 1;
302 else
304 for (bitno = bitoff; word; bitno++)
306 if (word & 1)
308 list[count++] = bitno;
309 if (count >= num)
311 *next = bitno + 1;
312 return count;
315 word >>= 1;
320 *next = bitoff;
321 return count;
325 /* Ensure that any unused bits within the last word are clear. */
326 static inline void
327 vbitset_unused_clear (dst)
328 bitset dst;
330 unsigned int last_bit;
332 last_bit = BITSET_SIZE_ (dst) % BITSET_WORD_BITS;
333 if (last_bit)
334 VBITSET_WORDS (dst)[VBITSET_SIZE (dst) - 1] &=
335 ((bitset_word) 1 << last_bit) - 1;
339 static void
340 vbitset_ones (bitset dst)
342 bitset_word *dstp = VBITSET_WORDS (dst);
343 unsigned int bytes;
345 bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
347 memset (dstp, -1, bytes);
348 vbitset_unused_clear (dst);
352 static void
353 vbitset_zero (bitset dst)
355 bitset_word *dstp = VBITSET_WORDS (dst);
356 unsigned int bytes;
358 bytes = sizeof (bitset_word) * VBITSET_SIZE (dst);
360 memset (dstp, 0, bytes);
364 static bool
365 vbitset_empty_p (bitset dst)
367 unsigned int i;
368 bitset_word *dstp = VBITSET_WORDS (dst);
370 for (i = 0; i < VBITSET_SIZE (dst); i++)
371 if (dstp[i])
372 return 0;
374 return 1;
378 static void
379 vbitset_copy1 (bitset dst, bitset src)
381 bitset_word *srcp;
382 bitset_word *dstp;
383 bitset_windex ssize;
384 bitset_windex dsize;
386 if (src == dst)
387 return;
389 vbitset_resize (dst, BITSET_SIZE_ (src));
391 srcp = VBITSET_WORDS (src);
392 dstp = VBITSET_WORDS (dst);
393 ssize = VBITSET_SIZE (src);
394 dsize = VBITSET_SIZE (dst);
396 memcpy (dstp, srcp, sizeof (bitset_word) * ssize);
398 memset (dstp + sizeof (bitset_word) * ssize, 0,
399 sizeof (bitset_word) * (dsize - ssize));
403 static void
404 vbitset_not (bitset dst, bitset src)
406 unsigned int i;
407 bitset_word *srcp;
408 bitset_word *dstp;
409 bitset_windex ssize;
410 bitset_windex dsize;
412 vbitset_resize (dst, BITSET_SIZE_ (src));
414 srcp = VBITSET_WORDS (src);
415 dstp = VBITSET_WORDS (dst);
416 ssize = VBITSET_SIZE (src);
417 dsize = VBITSET_SIZE (dst);
419 for (i = 0; i < ssize; i++)
420 *dstp++ = ~(*srcp++);
422 vbitset_unused_clear (dst);
423 memset (dstp + sizeof (bitset_word) * ssize, 0,
424 sizeof (bitset_word) * (dsize - ssize));
428 static bool
429 vbitset_equal_p (bitset dst, bitset src)
431 unsigned int i;
432 bitset_word *srcp = VBITSET_WORDS (src);
433 bitset_word *dstp = VBITSET_WORDS (dst);
434 bitset_windex ssize = VBITSET_SIZE (src);
435 bitset_windex dsize = VBITSET_SIZE (dst);
437 for (i = 0; i < min (ssize, dsize); i++)
438 if (*srcp++ != *dstp++)
439 return 0;
441 if (ssize > dsize)
443 for (; i < ssize; i++)
444 if (*srcp++)
445 return 0;
447 else
449 for (; i < dsize; i++)
450 if (*dstp++)
451 return 0;
454 return 1;
458 static bool
459 vbitset_subset_p (bitset dst, bitset src)
461 unsigned int i;
462 bitset_word *srcp = VBITSET_WORDS (src);
463 bitset_word *dstp = VBITSET_WORDS (dst);
464 bitset_windex ssize = VBITSET_SIZE (src);
465 bitset_windex dsize = VBITSET_SIZE (dst);
467 for (i = 0; i < min (ssize, dsize); i++, dstp++, srcp++)
468 if (*dstp != (*srcp | *dstp))
469 return 0;
471 if (ssize > dsize)
473 for (; i < ssize; i++)
474 if (*srcp++)
475 return 0;
478 return 1;
482 static bool
483 vbitset_disjoint_p (bitset dst, bitset src)
485 unsigned int i;
486 bitset_word *srcp = VBITSET_WORDS (src);
487 bitset_word *dstp = VBITSET_WORDS (dst);
488 bitset_windex ssize = VBITSET_SIZE (src);
489 bitset_windex dsize = VBITSET_SIZE (dst);
491 for (i = 0; i < min (ssize, dsize); i++)
492 if (*srcp++ & *dstp++)
493 return 0;
495 return 1;
499 static void
500 vbitset_and (bitset dst, bitset src1, bitset src2)
502 unsigned int i;
503 bitset_word *src1p;
504 bitset_word *src2p;
505 bitset_word *dstp;
506 bitset_windex ssize1;
507 bitset_windex ssize2;
508 bitset_windex dsize;
510 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
512 dsize = VBITSET_SIZE (dst);
513 ssize1 = VBITSET_SIZE (src1);
514 ssize2 = VBITSET_SIZE (src2);
515 dstp = VBITSET_WORDS (dst);
516 src1p = VBITSET_WORDS (src1);
517 src2p = VBITSET_WORDS (src2);
519 for (i = 0; i < min (ssize1, ssize2); i++)
520 *dstp++ = *src1p++ & *src2p++;
522 memset (dstp, 0, sizeof (bitset_word) * (dsize - min (ssize1, ssize2)));
526 static bool
527 vbitset_and_cmp (bitset dst, bitset src1, bitset src2)
529 unsigned int i;
530 int changed = 0;
531 bitset_word *src1p;
532 bitset_word *src2p;
533 bitset_word *dstp;
534 bitset_windex ssize1;
535 bitset_windex ssize2;
536 bitset_windex dsize;
538 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
540 dsize = VBITSET_SIZE (dst);
541 ssize1 = VBITSET_SIZE (src1);
542 ssize2 = VBITSET_SIZE (src2);
543 dstp = VBITSET_WORDS (dst);
544 src1p = VBITSET_WORDS (src1);
545 src2p = VBITSET_WORDS (src2);
547 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
549 bitset_word tmp = *src1p++ & *src2p++;
551 if (*dstp != tmp)
553 changed = 1;
554 *dstp = tmp;
558 if (ssize2 > ssize1)
560 src1p = src2p;
561 ssize1 = ssize2;
564 for (; i < ssize1; i++, dstp++)
566 if (*dstp != 0)
568 changed = 1;
569 *dstp = 0;
573 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
575 return changed;
579 static void
580 vbitset_andn (bitset dst, bitset src1, bitset src2)
582 unsigned int i;
583 bitset_word *src1p;
584 bitset_word *src2p;
585 bitset_word *dstp;
586 bitset_windex ssize1;
587 bitset_windex ssize2;
588 bitset_windex dsize;
590 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
592 dsize = VBITSET_SIZE (dst);
593 ssize1 = VBITSET_SIZE (src1);
594 ssize2 = VBITSET_SIZE (src2);
595 dstp = VBITSET_WORDS (dst);
596 src1p = VBITSET_WORDS (src1);
597 src2p = VBITSET_WORDS (src2);
599 for (i = 0; i < min (ssize1, ssize2); i++)
600 *dstp++ = *src1p++ & ~(*src2p++);
602 if (ssize2 > ssize1)
604 for (; i < ssize2; i++)
605 *dstp++ = 0;
607 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
609 else
611 for (; i < ssize1; i++)
612 *dstp++ = *src1p++;
614 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
619 static bool
620 vbitset_andn_cmp (bitset dst, bitset src1, bitset src2)
622 unsigned int i;
623 int changed = 0;
624 bitset_word *src1p;
625 bitset_word *src2p;
626 bitset_word *dstp;
627 bitset_windex ssize1;
628 bitset_windex ssize2;
629 bitset_windex dsize;
631 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
633 dsize = VBITSET_SIZE (dst);
634 ssize1 = VBITSET_SIZE (src1);
635 ssize2 = VBITSET_SIZE (src2);
636 dstp = VBITSET_WORDS (dst);
637 src1p = VBITSET_WORDS (src1);
638 src2p = VBITSET_WORDS (src2);
640 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
642 bitset_word tmp = *src1p++ & ~(*src2p++);
644 if (*dstp != tmp)
646 changed = 1;
647 *dstp = tmp;
651 if (ssize2 > ssize1)
653 for (; i < ssize2; i++, dstp++)
655 if (*dstp != 0)
657 changed = 1;
658 *dstp = 0;
662 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize2));
664 else
666 for (; i < ssize1; i++, dstp++)
668 bitset_word tmp = *src1p++;
670 if (*dstp != tmp)
672 changed = 1;
673 *dstp = tmp;
677 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
680 return changed;
684 static void
685 vbitset_or (bitset dst, bitset src1, bitset src2)
687 unsigned int i;
688 bitset_word *src1p;
689 bitset_word *src2p;
690 bitset_word *dstp;
691 bitset_windex ssize1;
692 bitset_windex ssize2;
693 bitset_windex dsize;
695 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
697 dsize = VBITSET_SIZE (dst);
698 ssize1 = VBITSET_SIZE (src1);
699 ssize2 = VBITSET_SIZE (src2);
700 dstp = VBITSET_WORDS (dst);
701 src1p = VBITSET_WORDS (src1);
702 src2p = VBITSET_WORDS (src2);
704 for (i = 0; i < min (ssize1, ssize2); i++)
705 *dstp++ = *src1p++ | *src2p++;
707 if (ssize2 > ssize1)
709 src1p = src2p;
710 ssize1 = ssize2;
713 for (; i < ssize1; i++)
714 *dstp++ = *src1p++;
716 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
720 static bool
721 vbitset_or_cmp (bitset dst, bitset src1, bitset src2)
723 unsigned int i;
724 int changed = 0;
725 bitset_word *src1p;
726 bitset_word *src2p;
727 bitset_word *dstp;
728 bitset_windex ssize1;
729 bitset_windex ssize2;
730 bitset_windex dsize;
732 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
734 dsize = VBITSET_SIZE (dst);
735 ssize1 = VBITSET_SIZE (src1);
736 ssize2 = VBITSET_SIZE (src2);
737 dstp = VBITSET_WORDS (dst);
738 src1p = VBITSET_WORDS (src1);
739 src2p = VBITSET_WORDS (src2);
741 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
743 bitset_word tmp = *src1p++ | *src2p++;
745 if (*dstp != tmp)
747 changed = 1;
748 *dstp = tmp;
752 if (ssize2 > ssize1)
754 src1p = src2p;
755 ssize1 = ssize2;
758 for (; i < ssize1; i++, dstp++)
760 bitset_word tmp = *src1p++;
762 if (*dstp != tmp)
764 changed = 1;
765 *dstp = tmp;
769 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
771 return changed;
775 static void
776 vbitset_xor (bitset dst, bitset src1, bitset src2)
778 unsigned int i;
779 bitset_word *src1p;
780 bitset_word *src2p;
781 bitset_word *dstp;
782 bitset_windex ssize1;
783 bitset_windex ssize2;
784 bitset_windex dsize;
786 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
788 dsize = VBITSET_SIZE (dst);
789 ssize1 = VBITSET_SIZE (src1);
790 ssize2 = VBITSET_SIZE (src2);
791 dstp = VBITSET_WORDS (dst);
792 src1p = VBITSET_WORDS (src1);
793 src2p = VBITSET_WORDS (src2);
795 for (i = 0; i < min (ssize1, ssize2); i++)
796 *dstp++ = *src1p++ ^ *src2p++;
798 if (ssize2 > ssize1)
800 src1p = src2p;
801 ssize1 = ssize2;
804 for (; i < ssize1; i++)
805 *dstp++ = *src1p++;
807 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
811 static bool
812 vbitset_xor_cmp (bitset dst, bitset src1, bitset src2)
814 unsigned int i;
815 int changed = 0;
816 bitset_word *src1p;
817 bitset_word *src2p;
818 bitset_word *dstp;
819 bitset_windex ssize1;
820 bitset_windex ssize2;
821 bitset_windex dsize;
823 vbitset_resize (dst, max (BITSET_SIZE_ (src1), BITSET_SIZE_ (src2)));
825 dsize = VBITSET_SIZE (dst);
826 ssize1 = VBITSET_SIZE (src1);
827 ssize2 = VBITSET_SIZE (src2);
828 dstp = VBITSET_WORDS (dst);
829 src1p = VBITSET_WORDS (src1);
830 src2p = VBITSET_WORDS (src2);
832 for (i = 0; i < min (ssize1, ssize2); i++, dstp++)
834 bitset_word tmp = *src1p++ ^ *src2p++;
836 if (*dstp != tmp)
838 changed = 1;
839 *dstp = tmp;
843 if (ssize2 > ssize1)
845 src1p = src2p;
846 ssize1 = ssize2;
849 for (; i < ssize1; i++, dstp++)
851 bitset_word tmp = *src1p++;
853 if (*dstp != tmp)
855 changed = 1;
856 *dstp = tmp;
860 memset (dstp, 0, sizeof (bitset_word) * (dsize - ssize1));
862 return changed;
866 /* FIXME, these operations need fixing for different size
867 bitsets. */
869 static void
870 vbitset_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
872 unsigned int i;
873 bitset_word *src1p;
874 bitset_word *src2p;
875 bitset_word *src3p;
876 bitset_word *dstp;
877 bitset_windex size;
879 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
880 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
882 bitset_and_or_ (dst, src1, src2, src3);
883 return;
886 vbitset_resize (dst, BITSET_NBITS_ (src1));
888 src1p = VBITSET_WORDS (src1);
889 src2p = VBITSET_WORDS (src2);
890 src3p = VBITSET_WORDS (src3);
891 dstp = VBITSET_WORDS (dst);
892 size = VBITSET_SIZE (dst);
894 for (i = 0; i < size; i++)
895 *dstp++ = (*src1p++ & *src2p++) | *src3p++;
899 static bool
900 vbitset_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
902 unsigned int i;
903 int changed = 0;
904 bitset_word *src1p;
905 bitset_word *src2p;
906 bitset_word *src3p;
907 bitset_word *dstp;
908 bitset_windex size;
910 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
911 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
912 return bitset_and_or_cmp_ (dst, src1, src2, src3);
914 vbitset_resize (dst, BITSET_NBITS_ (src1));
916 src1p = VBITSET_WORDS (src1);
917 src2p = VBITSET_WORDS (src2);
918 src3p = VBITSET_WORDS (src3);
919 dstp = VBITSET_WORDS (dst);
920 size = VBITSET_SIZE (dst);
922 for (i = 0; i < size; i++, dstp++)
924 bitset_word tmp = (*src1p++ & *src2p++) | *src3p++;
926 if (*dstp != tmp)
928 changed = 1;
929 *dstp = tmp;
932 return changed;
936 static void
937 vbitset_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
939 unsigned int i;
940 bitset_word *src1p;
941 bitset_word *src2p;
942 bitset_word *src3p;
943 bitset_word *dstp;
944 bitset_windex size;
946 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
947 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
949 bitset_andn_or_ (dst, src1, src2, src3);
950 return;
953 vbitset_resize (dst, BITSET_NBITS_ (src1));
955 src1p = VBITSET_WORDS (src1);
956 src2p = VBITSET_WORDS (src2);
957 src3p = VBITSET_WORDS (src3);
958 dstp = VBITSET_WORDS (dst);
959 size = VBITSET_SIZE (dst);
961 for (i = 0; i < size; i++)
962 *dstp++ = (*src1p++ & ~(*src2p++)) | *src3p++;
966 static bool
967 vbitset_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
969 unsigned int i;
970 int changed = 0;
971 bitset_word *src1p;
972 bitset_word *src2p;
973 bitset_word *src3p;
974 bitset_word *dstp;
975 bitset_windex size;
977 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
978 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
979 return bitset_andn_or_cmp_ (dst, src1, src2, src3);
981 vbitset_resize (dst, BITSET_NBITS_ (src1));
983 src1p = VBITSET_WORDS (src1);
984 src2p = VBITSET_WORDS (src2);
985 src3p = VBITSET_WORDS (src3);
986 dstp = VBITSET_WORDS (dst);
987 size = VBITSET_SIZE (dst);
989 for (i = 0; i < size; i++, dstp++)
991 bitset_word tmp = (*src1p++ & ~(*src2p++)) | *src3p++;
993 if (*dstp != tmp)
995 changed = 1;
996 *dstp = tmp;
999 return changed;
1003 static void
1004 vbitset_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
1006 unsigned int i;
1007 bitset_word *src1p;
1008 bitset_word *src2p;
1009 bitset_word *src3p;
1010 bitset_word *dstp;
1011 bitset_windex size;
1013 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
1014 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
1016 bitset_or_and_ (dst, src1, src2, src3);
1017 return;
1020 vbitset_resize (dst, BITSET_NBITS_ (src1));
1022 src1p = VBITSET_WORDS (src1);
1023 src2p = VBITSET_WORDS (src2);
1024 src3p = VBITSET_WORDS (src3);
1025 dstp = VBITSET_WORDS (dst);
1026 size = VBITSET_SIZE (dst);
1028 for (i = 0; i < size; i++)
1029 *dstp++ = (*src1p++ | *src2p++) & *src3p++;
1033 static bool
1034 vbitset_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
1036 unsigned int i;
1037 int changed = 0;
1038 bitset_word *src1p;
1039 bitset_word *src2p;
1040 bitset_word *src3p;
1041 bitset_word *dstp;
1042 bitset_windex size;
1044 if (BITSET_NBITS_ (src1) != BITSET_NBITS_ (src2)
1045 || BITSET_NBITS_ (src1) != BITSET_NBITS_ (src3))
1046 return bitset_or_and_cmp_ (dst, src1, src2, src3);
1048 vbitset_resize (dst, BITSET_NBITS_ (src1));
1050 src1p = VBITSET_WORDS (src1);
1051 src2p = VBITSET_WORDS (src2);
1052 src3p = VBITSET_WORDS (src3);
1053 dstp = VBITSET_WORDS (dst);
1054 size = VBITSET_SIZE (dst);
1056 for (i = 0; i < size; i++, dstp++)
1058 bitset_word tmp = (*src1p++ | *src2p++) & *src3p++;
1060 if (*dstp != tmp)
1062 changed = 1;
1063 *dstp = tmp;
1066 return changed;
1070 static void
1071 vbitset_copy (bitset dst, bitset src)
1073 if (BITSET_COMPATIBLE_ (dst, src))
1074 vbitset_copy1 (dst, src);
1075 else
1076 bitset_copy_ (dst, src);
1080 /* Vector of operations for multiple word bitsets. */
1081 struct bitset_vtable vbitset_vtable = {
1082 vbitset_set,
1083 vbitset_reset,
1084 bitset_toggle_,
1085 vbitset_test,
1086 vbitset_resize,
1087 bitset_size_,
1088 bitset_count_,
1089 vbitset_empty_p,
1090 vbitset_ones,
1091 vbitset_zero,
1092 vbitset_copy,
1093 vbitset_disjoint_p,
1094 vbitset_equal_p,
1095 vbitset_not,
1096 vbitset_subset_p,
1097 vbitset_and,
1098 vbitset_and_cmp,
1099 vbitset_andn,
1100 vbitset_andn_cmp,
1101 vbitset_or,
1102 vbitset_or_cmp,
1103 vbitset_xor,
1104 vbitset_xor_cmp,
1105 vbitset_and_or,
1106 vbitset_and_or_cmp,
1107 vbitset_andn_or,
1108 vbitset_andn_or_cmp,
1109 vbitset_or_and,
1110 vbitset_or_and_cmp,
1111 vbitset_list,
1112 vbitset_list_reverse,
1113 NULL,
1114 BITSET_VARRAY
1118 size_t
1119 vbitset_bytes (n_bits)
1120 bitset_bindex n_bits ATTRIBUTE_UNUSED;
1122 return sizeof (struct vbitset_struct);
1126 bitset
1127 vbitset_init (bset, n_bits)
1128 bitset bset;
1129 bitset_bindex n_bits;
1131 bset->b.vtable = &vbitset_vtable;
1133 bset->b.cindex = 0;
1135 VBITSET_SIZE (bset) = 0;
1136 vbitset_resize (bset, n_bits);
1137 return bset;